Skip to content
This repository has been archived by the owner on Jul 12, 2022. It is now read-only.

Commit

Permalink
CLI Additions (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
ansermino authored Jun 26, 2020
1 parent 3b853f4 commit 53b7c4d
Show file tree
Hide file tree
Showing 9 changed files with 201 additions and 67 deletions.
4 changes: 2 additions & 2 deletions cb-sol-cli/Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
SOL_URL=https://github.com/ChainSafe/chainbridge-solidity

SOL_VERSION="v0.0.2-alpha"

fetch-contracts:
@echo " > \033[32mFetching chainbridge-solidity contracts... \033[0m "
git clone ${SOL_URL} && cd chainbridge-solidity && git checkout ${GIT_COMMIT}
git clone ${SOL_URL} && cd chainbridge-solidity && git checkout ${SOL_VERSION}

compile:
cd chainbridge-solidity && npm install && npx truffle compile
Expand Down
48 changes: 30 additions & 18 deletions cb-sol-cli/cmd/bridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,23 +59,6 @@ const setBurnCmd = new Command("set-burn")
await waitForTx(args.provider, tx.hash)
})

const queryProposalCmd = new Command("query-proposal")
.description("Query a proposal on-chain")
.option('--bridge <address>', 'Bridge contract address', constants.BRIDGE_ADDRESS)
.option('--depositNonce <address>', 'Nonce of proposal', 0)
.option('--chainId <id>', 'Source chain ID of proposal', constants.DEFAULT_SOURCE_ID)
.action(async function (args) {
await setupParentArgs(args, args.parent.parent)

// Instances
const bridgeInstance = new ethers.Contract(args.bridge, constants.ContractABIs.Bridge.abi, args.wallet);

const prop = await bridgeInstance.getProposal(args.chainId, args.depositNonce)
log(args, `Source: ${args.chainId} Nonce: ${args.depositNonce}`)
log(args, `Votes: ${prop._yesVotes} Status: ${prop._status}`)
})


const cancelProposalCmd = new Command("cancel-proposal")
.description("Cancel a proposal that has passed the expiry threshold")
.option('--bridge <address>', 'Bridge contract address', constants.BRIDGE_ADDRESS)
Expand All @@ -90,12 +73,41 @@ const cancelProposalCmd = new Command("cancel-proposal")
await waitForTx(args.provider, tx.hash)
})

const queryProposalCmd = new Command("query-proposal")
.description("Queries a proposal")
.option('--bridge <address>', 'Bridge contract address', constants.BRIDGE_ADDRESS)
.option('--chainId <id>', 'Source chain ID of proposal', 0)
.option('--depositNonce <value>', 'Deposit nonce of proposal', 0)
.option('--dataHash <value>', 'Hash of proposal metadata', constants.ERC20_PROPOSAL_HASH)
.action(async function (args) {
await setupParentArgs(args, args.parent.parent)
const bridgeInstance = new ethers.Contract(args.bridge, constants.ContractABIs.Bridge.abi, args.wallet);

const prop = await bridgeInstance.getProposal(args.chainId, args.depositNonce, args.dataHash)

console.log(prop)
})

const queryResourceId = new Command("query-resource")
.description("Query the contract address associated with a resource ID")
.option('--handler <address>', 'Handler contract address', constants.ERC20_HANDLER_ADDRESS)
.option('--resourceId <address>', `ResourceID to query`, constants.ERC20_RESOURCEID)
.action(async function(args) {
await setupParentArgs(args, args.parent.parent)

const handlerInstance = new ethers.Contract(args.handler, constants.ContractABIs.HandlerHelpers.abi, args.wallet)
const address = await handlerInstance._resourceIDToTokenContractAddress(args.resourceId)
log(args, `Resource ID ${args.resourceId} is mapped to contract ${address}`)
})


const bridgeCmd = new Command("bridge")

bridgeCmd.addCommand(registerResourceCmd)
bridgeCmd.addCommand(registerGenericResourceCmd)
bridgeCmd.addCommand(setBurnCmd)
bridgeCmd.addCommand(queryProposalCmd)
bridgeCmd.addCommand(cancelProposalCmd)
bridgeCmd.addCommand(queryProposalCmd)
bridgeCmd.addCommand(queryResourceId)

module.exports = bridgeCmd
44 changes: 41 additions & 3 deletions cb-sol-cli/cmd/erc20.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,13 @@ const depositCmd = new Command("deposit")
const bridgeInstance = new ethers.Contract(args.bridge, constants.ContractABIs.Bridge.abi, args.wallet);

const data = '0x' +
args.resourceId.substr(2) + // OriginHandlerAddress (32 bytes)
ethers.utils.hexZeroPad(ethers.utils.hexlify(Number(args.amount)), 32).substr(2) + // Deposit Amount (32 bytes)
ethers.utils.hexZeroPad(ethers.utils.bigNumberify(args.amount).toHexString(), 32).substr(2) + // Deposit Amount (32 bytes)
ethers.utils.hexZeroPad(ethers.utils.hexlify((args.recipient.length - 2)/2), 32).substr(2) + // len(recipientAddress) (32 bytes)
args.recipient.substr(2); // recipientAddress (?? bytes)

log(args, `Constructed deposit:`)
log(args, ` Resource Id: ${args.resourceId}`)
log(args, ` Amount: ${args.amount}`)
log(args, ` Amount: ${ethers.utils.bigNumberify(args.amount).toHexString()}`)
log(args, ` len(recipient): ${(args.recipient.length - 2)/ 2}`)
log(args, ` Recipient: ${args.recipient}`)
log(args, ` Raw: ${data}`)
Expand Down Expand Up @@ -93,12 +92,51 @@ const balanceCmd = new Command("balance")
log(args, `Account ${args.address} has a balance of ${balance}` )
})

const allowanceCmd = new Command("allowance")
.description("Get the allowance of a spender for an address")
.option('--spender <address>', 'Address of spender', constants.ERC20_HANDLER_ADDRESS)
.option('--owner <address>', 'Address of token owner', constants.deployerAddress)
.option('--erc20Address <address>', 'ERC20 contract address', constants.ERC20_ADDRESS)
.action(async function(args) {
await setupParentArgs(args, args.parent.parent)

const erc20Instance = new ethers.Contract(args.erc20Address, constants.ContractABIs.Erc20Mintable.abi, args.wallet);
const allowance = await erc20Instance.allowance(args.owner, args.spender)

log(args, `Spender ${args.spender} is allowed to spend ${allowance} tokens on behalf of ${args.owner}`)
})

const createErc20ProposalData = (amount, recipient) => {
if (recipient.substr(0, 2) === "0x") {
recipient = recipient.substr(2)
}
return '0x' +
ethers.utils.hexZeroPad(ethers.utils.bigNumberify(amount).toHexString(), 32).substr(2) +
ethers.utils.hexZeroPad(ethers.utils.hexlify(recipient.length / 2 + recipient.length % 2), 32).substr(2) +
recipient;
}

const proposalDataHashCmd = new Command("data-hash")
.description("Hash the proposal data for an erc20 proposal")
.option('--amount <value>', "Amount to transfer", 1)
.option('--recipient <address>', 'Destination recipient address', constants.relayerAddresses[4])
.option('--handler <address>', 'ERC20 handler address', constants.ERC20_HANDLER_ADDRESS)
.action(async function(args) {

const data = createErc20ProposalData(args.amount, args.recipient)
const hash = ethers.utils.solidityKeccak256(["address", "bytes"], [args.handler, data])

log(args, `Hash: ${hash} Data: ${data}`)
})

const erc20Cmd = new Command("erc20")

erc20Cmd.addCommand(mintCmd)
erc20Cmd.addCommand(addMinterCmd)
erc20Cmd.addCommand(approveCmd)
erc20Cmd.addCommand(depositCmd)
erc20Cmd.addCommand(balanceCmd)
erc20Cmd.addCommand(allowanceCmd)
erc20Cmd.addCommand(proposalDataHashCmd)

module.exports = erc20Cmd
45 changes: 39 additions & 6 deletions cb-sol-cli/cmd/erc721.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const addMinterCmd = new Command("add-minter")
.description("Add a new minter to the contract")
.option('--erc721Address <address>', 'ERC721 contract address', constants.ERC721_ADDRESS)
.option('--minter <address>', 'Minter address', constants.relayerAddresses[1])
.action(async function(args) {
.action(async function (args) {
await setupParentArgs(args, args.parent.parent)
const erc721Instance = new ethers.Contract(args.erc721Address, constants.ContractABIs.Erc721Mintable.abi, args.wallet);
const MINTER_ROLE = await erc721Instance.MINTER_ROLE()
Expand All @@ -52,7 +52,10 @@ const approveCmd = new Command("approve")
const erc721Instance = new ethers.Contract(args.erc721Address, constants.ContractABIs.Erc721Mintable.abi, args.wallet);

log(args, `Approving ${args.recipient} to spend token ${args.id} from ${args.wallet.address} on contract ${args.erc721Address}!`);
const tx = await erc721Instance.approve(args.recipient, ethers.utils.hexlify(args.id), { gasPrice: args.gasPrice, gasLimit: args.gasLimit});
const tx = await erc721Instance.approve(args.recipient, ethers.utils.hexlify(args.id), {
gasPrice: args.gasPrice,
gasLimit: args.gasLimit
});
await waitForTx(args.provider, tx.hash)
})

Expand All @@ -70,15 +73,14 @@ const depositCmd = new Command("deposit")
const bridgeInstance = new ethers.Contract(args.bridge, constants.ContractABIs.Bridge.abi, args.wallet);

const data = '0x' +
args.resourceId.substr(2) + // resourceID (32 bytes) for now
ethers.utils.hexZeroPad(ethers.utils.hexlify(args.id), 32).substr(2) + // Deposit Amount (32 bytes)
ethers.utils.hexZeroPad(ethers.utils.hexlify((args.recipient.length - 2)/2), 32).substr(2) + // len(recipientAddress) (32 bytes)
ethers.utils.hexZeroPad(ethers.utils.hexlify((args.recipient.length - 2) / 2), 32).substr(2) + // len(recipientAddress) (32 bytes)
ethers.utils.hexlify(args.recipient).substr(2) // recipientAddress (?? bytes)

log(args, `Constructed deposit:`)
log(args, ` Resource Id: ${args.resourceId}`)
log(args, ` Token Id: ${args.id}`)
log(args, ` len(recipient): ${(args.recipient.length - 2)/2}`)
log(args, ` len(recipient): ${(args.recipient.length - 2) / 2}`)
log(args, ` Recipient: ${args.recipient}`)
log(args, ` Raw: ${data}`)
log(args, "Creating deposit to initiate transfer!")
Expand All @@ -88,16 +90,47 @@ const depositCmd = new Command("deposit")
args.dest, // destination chain id
args.resourceId,
data,
{ gasPrice: args.gasPrice, gasLimit: args.gasLimit});
{gasPrice: args.gasPrice, gasLimit: args.gasLimit});
await waitForTx(args.provider, tx.hash)
})

const createErc721ProposalData = (id, recipient, metadata) => {
if (recipient.substr(0, 2) === "0x") {
recipient = recipient.substr(2)
}
if (metadata.substr(0, 2) === "0x") {
metadata = metadata.substr(2)
}
console.log(metadata)
return '0x' +
ethers.utils.hexZeroPad(ethers.utils.bigNumberify(id).toHexString(), 32).substr(2) +
ethers.utils.hexZeroPad(ethers.utils.hexlify(recipient.length / 2 + recipient.length % 2), 32).substr(2) +
recipient +
ethers.utils.hexZeroPad(ethers.utils.hexlify(metadata.length / 2 + metadata.length % 2), 32).substr(2) +
metadata;
}

const proposalDataHashCmd = new Command("data-hash")
.description("Hash the proposal data for an erc721 proposal")
.option('--id <value>', "Token ID", 1)
.option('--recipient <address>', 'Destination recipient address', constants.relayerAddresses[4])
.option('--metadata <metadata>', 'Token metadata', "")
.option('--handler <address>', 'ERC721 handler address', constants.ERC20_HANDLER_ADDRESS)
.action(async function (args) {
console.log(args.metadata)
const data = createErc721ProposalData(args.id, args.recipient, args.metadata)
const hash = ethers.utils.solidityKeccak256(["address", "bytes"], [args.handler, data])

log(args, `Hash: ${hash} Data: ${data}`)
})

const erc721Cmd = new Command("erc721")

erc721Cmd.addCommand(mintCmd)
erc721Cmd.addCommand(ownerCmd)
erc721Cmd.addCommand(addMinterCmd)
erc721Cmd.addCommand(approveCmd)
erc721Cmd.addCommand(depositCmd)
erc721Cmd.addCommand(proposalDataHashCmd)

module.exports = erc721Cmd
4 changes: 3 additions & 1 deletion cb-sol-cli/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ const ContractABIs = {
Erc721Handler: require(CONTRACT_PATH + "/ERC721Handler.json"),
Erc721Mintable: require(CONTRACT_PATH + "/ERC721MinterBurnerPauser.json"),
GenericHandler: require(CONTRACT_PATH + "/GenericHandler.json"),
CentrifugeAssetStore: require(CONTRACT_PATH + "/CentrifugeAsset.json")
CentrifugeAssetStore: require(CONTRACT_PATH + "/CentrifugeAsset.json"),
HandlerHelpers: require(CONTRACT_PATH + "/HandlerHelpers.json")
}

module.exports.ContractABIs = ContractABIs
Expand Down Expand Up @@ -53,3 +54,4 @@ module.exports.ERC20_RESOURCEID = ethers.utils.hexZeroPad((this.ERC20_ADDRESS +
module.exports.ERC721_RESOURCEID = ethers.utils.hexZeroPad((this.ERC721_ADDRESS + ethers.utils.hexlify(this.DEFAULT_SOURCE_ID).substr(2)), 32);
module.exports.GENERIC_RESOURCEID = ethers.utils.hexZeroPad((this.CENTRIFUGE_ASSET_STORE_ADDRESS + ethers.utils.hexlify(this.DEFAULT_SOURCE_ID).substr(2)), 32);

module.exports.ERC20_PROPOSAL_HASH = "0x19b14d095647bb784f237072e14df1133fbd2008c5039c469321d77099a7b6da"
31 changes: 21 additions & 10 deletions cb-sol-cli/docs/bridge.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
- [`register-resource`](#register-resource)
- [`register-generic-resource`](#register-generic-resource)
- [`set-burn`](#set-burn)
- [`query-proposal`](#query-proposal)
- [`cancel-proposal`](#cancel-proposal)
- [`query-proposal`](#query-proposal)
- [`query-resource`](#query-resouce)


## `register-resource`
Expand Down Expand Up @@ -41,15 +42,6 @@ Set a token contract as mintable/burnable in a handler.
--tokenContract <address> Token contract to be registered
```

## `query-proposal`
Query a proposal on-chain.

```
--bridge <address> Bridge contract address
--depositNonce <address> Nonce of proposal
--chainId <id> Source chain ID of proposal
```

## `cancel-proposal`
Cancels an expired proposal.

Expand All @@ -58,3 +50,22 @@ Cancels an expired proposal.
--chainId <id> Chain ID of proposal to cancel
--depositNonce <value> Deposit nonce of proposal to cancel
```

## `query-proposal`
Queries an inbound proposal.

```
--bridge <address> Bridge contract address
--chainId <id> Source chain ID of proposal
--depositNonce <value> Deposit nonce of proposal
--dataHash <value> Hash of proposal metadata
```

## `query-resouce`
Queries the contract address associated with the provided resource ID for a specific handler contract.

```
--handler <address> Handler contract address
--resourceId <address> ResourceID to query
```
20 changes: 20 additions & 0 deletions cb-sol-cli/docs/erc20.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
- [`approve`](#approve)
- [`deposit`](#deposit)
- [`balance`](#balance)
- [`allowance`](#allowance)
- [`data-hash`](#data-hash)

## `mint`
Mint tokens on an ERC20 mintable contract.
Expand Down Expand Up @@ -46,3 +48,21 @@ Query balance for an account in an ERC20 contract.
--address <address> Address to query
--erc20Address <address> ERC20 contract address
```

## `allowance`
Get the allowance of a spender for an address

```
--spender <address> Address of spender
--owner <address> Address of token owner
--erc20Address <address> ERC20 contract address
```

## `data-hash`
Constructs proposal data and returns the hash required for on-chain queries.

```
--amount <value> Amount to transfer
--recipient <address> Destination recipient address
--handler <address> ERC20 handler address
```
11 changes: 11 additions & 0 deletions cb-sol-cli/docs/erc721.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- [`add-minter`](#add-minter)
- [`approve`](#approve)
- [`deposit`](#deposit)
- [`data-hash`](#data-hash)

## `mint`
Mint tokens on an ERC721 mintable contract.
Expand Down Expand Up @@ -50,3 +51,13 @@ Initiate a transfer of ERC721 tokens.
--resourceId <resourceID> Resource ID for transfer
--bridge <address> Bridge contract address
```

## `data-hash`
Construct erc721 proposal data and provide hash for on-chain queries.

```
--id <value> Token ID
--recipient <address> Destination recipient address
--metadata <metadata> Token metadata
--handler <address> ERC721 handler address
```
Loading

0 comments on commit 53b7c4d

Please sign in to comment.