@pendulum-chain/api-solang
v0.7.2
Published
Interface to interact with smart contracts compiled via Solang
Downloads
169
Readme
Polkadot API for Smart Contracts compiled via Solang
This library allows to deploy and call into smart contracts that have been compiled from Solidity to wasm via Solang.
It has three main functions:
- deploy (instantiate) a smart contract
- execute a message call by submitting an extrinsic
- make a message call via RPC (dry-run)
These functions are meant to be used very flexibly and they have the following special features:
The first two functions allow to either specify a keypair or a general signer in order to sign the extrinsics. The keypair is generally useful for command line tools whereas the signer is more useful in a browser context, where it can give access to a wallets or browser extensions.
In certain applications it can be necessary to extend the extrinsics created in the first two functions, e.g., to wrap them into a sudo call. For that reason these functions allow to specify an optional argument
modifyExtrinsic
that allows the caller to arbitrarily change or extend the created extrinsic.Contracts usually emit events and these events can be emitted by contracts (recursively) called by the original contract. In order to properly decode the binary data contained in the event, one needs to lookup the abi of the respective contract emitting the event. For that reason the first two functions take an optional argument
lookupAbi
that allows the caller to provide the abi for any deployed contract (identified through the contract address).All functions can correctly decode the return value of message calls, i.e., whether a message call reverted (including the revert message) or whether it panicked and why it panicked.
The differences between the message call by extrinsic and the message call by RPC methods are:
- the dry-run does not cost any fees
- the dry-run does not require signatures or secret keys
- the dry-run is executed immediately, and does not need to wait for a block
- the dry-run returns an output value
- changes to the chain or contract storage during the dry-run will be discarded after the call
Deploy a smart contract
The function deployContract
has the following arguments:
api
: the polkadot-jsApiPromise
objectThis is the
ApiPromise
object that polkadot-js creates when connecting to an RPC node of a chain.abi
: The abi (metadata) of the smart contractThis needs to be an object of type
Abi
. It can be constructed from the metadata JSON file (that is generated by Solang) as follows:const metadata = JSON.parse(metadataString); new Abi(metadata, api.registry.getChainProperties());
signer
: Specifies the signer of the extrinsic submitted to the chain.This can either be a keypair or any generic signer. If it is a keypair, then it needs to have the format
{ type: "keypair"; keypair: KeyringPair; }
If it is a generic signer, then it needs to have the format
{ type: "signer"; address: string; // the address of the signer signer: Signer; }
constructorArguments
: the array with the arguments to the constructorconstructorName
: an optional argument to specify the constructorThis is
new
by default. Contracts that are compiled via Solidity usually only have thenew
constructor.limits
: the resource limitsThese limits specify the resources that are allowed to be used for the execution. They need to be specified as the type
{ gas: { refTime: string | number; proofSize: string | number; }; storageDeposit?: string | number; }
The
gas.refTime
andgas.proofSize
entries specify limits of the gas usage. The optional argumentstorageDeposit
specifies a limit for the storage deposit.modifyExtrinsic
: allows to extend the generated extrinsic.This is an optional function that allows the caller to extend, modify or wrap the extrinsic created by
deployContract
before it is submitted to the chain.lookupAbi
: provide abi for deployed contractsThis is an optional argument that allows to provide the abi of any deployed contract (specified by the address of the contract). This allows
deployContract
to properly decode events emitted during contract execuction.
The return value of this function is an object that contains the field type
. This fields indicate the execution status and is either one of the values:
"success"
: in this case the deployment was successful and the return object also contains the entriesevents
(which is the collection of (decoded) contract events that were emitted during contract execution), thedeploymentAddress
and thetransactionFee
that the signer had to pay"error"
: in this case there was a general error when submitting the extrinsic and the return object contains the entryerror
(a string with an error description)"reverted"
: in this case the contract reverted and the return object contains the revert message in the entrydescription
"panic"
: in this case the contract panicked and the return object contains the entrieserrorCode
(a numerical error code) andexplanation
(an explanation of the error code)
Execute a Message Call
The function executeMessage
has the following arguments:
api
: the polkadot-jsApiPromise
objectThis is the
ApiPromise
object that polkadot-js creates when connecting to an RPC node of a chain.abi
: The abi (metadata) of the smart contractThis needs to be an object of type
Abi
. It can be constructed from the metadata JSON file (that is generated by Solang) as follows:const metadata = JSON.parse(metadataString); new Abi(metadata, api.registry.getChainProperties());
contractDeploymentAddress
: the address of the contractThis needs to be the address of a deployed contracts that has the abi specified by
abi
callerAddress
: the address of the caller of the contractmessageName
: the name of the messagemessageArguments
: the array with the arguments to the messagelimits
: the resource limitsThese limits specify the resources that are allowed to be used for the execution. They need to be specified as the type
{ gas: { refTime: string | number; proofSize: string | number; }; storageDeposit?: string | number; }
The
gas.refTime
andgas.proofSize
entries specify limits of the gas usage. The optional argumentstorageDeposit
specifies a limit for the storage deposit.getSigner
: Specifies the signer of the extrinsic submitted to the chain.This callback will be invoked when an extrinsic is submitted to the chain. The address associated with the signer should be the same as
callerAddress
. This can either be a keypair or any generic signer. If it is a keypair, then it needs to have the format{ type: "keypair"; keypair: KeyringPair; }
If it is a generic signer, then it needs to have the format
{ type: "signer"; address: string; // the address of the signer signer: Signer; }
modifyExtrinsic
: allows to extend the generated extrinsic.This is an optional function that allows the caller to extend, modify or wrap the extrinsic created by
executeMessage
before it is submitted to the chain.lookupAbi
: provide abi for deployed contractsThis is an optional argument that allows to provide the abi of any deployed contract (specified by the address of the contract). This allows
executeMessage
to properly decode events emitted during contract execuction.
The return value of this function is an object that contains two entries execution
and result
. The execution
entry contains the field type
, which can be either one of
onlyQuery
: in this case only the rpc method has been executed because an error occurred before submitting an extrinsicextrinsic
: an extrinsic has been submitted to execute the message call – in this case theexecution
object also contains the entriescontractEvents
(which is the collection of (decoded) contract events that were emitted during contract execution) and thetransactionFee
that the signer had to pay
The result
object contains the entry gasMetrics
with the sub entries gasRequired
and gasConsumed
(both are a Weight
). Furthermore, it has the field type
which is either one of the following values:
"success"
: in this case the deployment was message call was successful and it contains a return value in the entryvalue
"error"
: in this case there was a general error when submitting the extrinsic and the return object contains the entryerror
(a string with an error description)"reverted"
: in this case the contract reverted and the return object contains the revert message in the entrydescription
"panic"
: in this case the contract panicked and the return object contains the entrieserrorCode
(a numerical error code) andexplanation
(an explanation of the error code)
Dry Run a Message Call (Read Message)
The function readMessage
has the following arguments:
api
: the polkadot-jsApiPromise
objectThis is the
ApiPromise
object that polkadot-js creates when connecting to an RPC node of a chain.abi
: The abi (metadata) of the smart contractThis needs to be an object of type
Abi
. It can be constructed from the metadata JSON file (that is generated by Solang) as follows:const metadata = JSON.parse(metadataString); new Abi(metadata, api.registry.getChainProperties());
contractDeploymentAddress
: the address of the contractThis needs to be the address of a deployed contracts that has the abi specified by
abi
callerAddress
: the address of the caller of the contractmessageName
: the name of the messagemessageArguments
: the array with the arguments to the messagelimits
: the resource limitsThese limits specify the resources that are allowed to be used for the execution. They need to be specified as the type
{ gas: { refTime: string | number; proofSize: string | number; }; storageDeposit?: string | number; }
The
gas.refTime
andgas.proofSize
entries specify limits of the gas usage. The optional argumentstorageDeposit
specifies a limit for the storage deposit.
The return value of this function contains the entry gasMetrics
with the sub entries gasRequired
and gasConsumed
(both are a Weight
). Furthermore, it has the field type
which is either one of the following values:
"success"
: in this case the deployment was message call was successful and it contains a return value in the entryvalue
"error"
: in this case there was a general error when submitting the extrinsic and the return object contains the entryerror
(a string with an error description)"reverted"
: in this case the contract reverted and the return object contains the revert message in the entrydescription
"panic"
: in this case the contract panicked and the return object contains the entrieserrorCode
(a numerical error code) andexplanation
(an explanation of the error code)
Submit an Extrinsic
Additionally this module also exposes a function signAndSubmitExtrinsic
that allows to submit an arbitrary extrinsic and that processes the chain events in order to determine the execution status of the extrinsic.
It has two arguments:
extrinsic
: the extrinsic itselfsigner
: as for the other two functions this specifies the signer of the extrinsic submitted to the chain.
This function only returns after the extrinsic has been executed on-chain. The return value of this function is an object with the following entries:
transactionFee
: the transaction fee that the signer had to pay for the executionevents
: the array of all Substrate events generated during executionstatus
: this is an object whosetype
entry is either"success"
or"error"
. In the latter case this object also contains the entryerror
, which is a string of the error message