Wrap contract deployment
Opened this issue · 6 comments
Contract deployment is a (relatively) common use case for front-end applications, especially contract generators/factories. It makes sense to wrap createcontract
and replicate the functionality of web3's Contract.new()
.
I therefore propose Contract.deploy(params: any[] = [], opts: IRPCCreateContractRequest = {}): Promise<IRPCCreateContractResult>
.
IRPCCreateContractRequest
is defined as:
export interface IRPCCreateContractRequest {
/**
* Bytecode of the contract to deploy
*/
bytecode?: string
/**
* gasLimit, default: 200000, max: 40000000
*/
gasLimit?: number
/**
* Qtum price per gas unit, default: 0.00000001, min:0.00000001
*/
gasPrice?: number | string
/**
* The quantum address that will be used as sender.
*/
senderAddress?: string;
}
and IRPCCreateContractResult
is defined as:
export interface IRPCCreateContractResult extends IRPCSendToContractResult {
/**
* Address of the deployed contract.
*/
address: string
}
In order to facilitate this, I also propose a function encodeConstructorParams
in abi.ts
similar to https://github.com/ethereum/web3.js/blob/2fba1d2f2b4c5c0afb286e30b6b756d33faf9c8a/lib/web3/contract.js#L36:
export function encodeConstructorParams(contract: IABIMethod[], params: any[] = []): string {
const types = contract.filter((method) => {
return method.type === "constructor" && method.inputs.length === params.length
}).map((method: IABIMethod) => {
return method.inputs.map((input) => {
return input.type
})
})[0] || ''
const calldata = encodeParams(types, params)
return calldata
}
This is implemented and tested in https://github.com/kfichter/qtumjs/commit/b0de48c6a4a5b20f06f9b0e412e006926363e0a8.
My only question is whether to implement Contract.deploy()
such that it sets the instance address to the address of the newly deployed contract. That's how Web3 handles this and I think it makes sense.
The implementation in https://github.com/kfichter/qtumjs/commit/b0de48c6a4a5b20f06f9b0e412e006926363e0a8 looks good.
However, I think deploy
being an instance method of Contract
makes the semantic rather strange.
I think a nicer API is to put this method on the Qtum object (this object knows about all the ABI information):
class Qtum extends QtumRPC
/**
* Read ABI and bytecode from `this.repo`, and call `createcontract`
* RPC call, and return an instantiated Contract.
*
* @param name The name of the contract definition.
*/
public deploy(name: string, opts: { sender?: string } = {}): Contract {
// call rpc to deploy the contract
}
}
And we add definitions
to IContractsRepoData
to contain ABI and bytecode.
The ContractsRepo
is able to instantiate a Contract with a logDecoder that knows about all event types.
Agreed. I pretty much just ripped that deployment syntax from web3 but I think you're right. I'll make those changes.
Thanks!
Btw, sorry for the slow response. I didn't get the GitHub notification (I wasn't a repo watcher and I didn't realize that)
Haha, no worries. Just trying to help out where I can.