All Products
Search
Document Center

Contract Interface

Last Updated: Jul 23, 2019

For the contract platform where contract-related operations are called frequently, BaaS has optimized the JS SDK to make contract operations easier and more efficient. Before you use contract-related operations, you need to understand the ABI and bytecodes. For more information, see Cloud IDE smart contract development environment.

In the following description, the sample codeCreditManager is from Solidity smart contract development.The JS SDK can be used with solc-js, a Solidity compiler. For more information about solc-js, see Compile contracts using Solidity.

Create a smart contract instance

You can run the contract code to create a smart contract instance. You can deploy and call this smart contract.

Request parameters

Parameter Required Type Description
name true string The name of the target smart contract. The identity of this contract is the hash value of the contract name.
abi true string ABI-based string in the JSON format.
vmType false string The smart contract platform supports both Solidity and C++ contract languages. To initialize a contract instance written in C++, you can configure this parameter aschain.WASM. This parameter is configured as chain.EVM by default.

Example 1

  1. java script
  2. const solc = require('@alipay/solc')
  3. const contract = fs.readFileSync('. /CreditManager.sol', {encoding: 'ascii'})
  4. // Set the second parameter to 1 to start compiling
  5. const output = solc.compile(contract, 1)
  6. const abi = JSON.parse(output.contracts[':CreditManager'].interface)
  7. const bytecode = output.contracts[':CreditManager'].bytecode
  8. // Add a timestamp to make sure that the identity of the contract name is unique
  9. const contractName = 'contract'+Date.now()
  10. // Initialize a smart contract instance
  11. let myContract = chain.ctr.contract(contractName, abi)

Example 2

Use the Wasm bytecode to initialize a contract written in C++.

  1. java script
  2. const wasm_code = fs.readFileSync('./contract/base.wasm')
  3. const abi = fs.readFileSync('./contract/base.abi')
  4. const bytecode = '0x'+wasm_code.toString('hex')
  5. // Add a timestamp to make sure that the identity of the contract name is unique
  6. const contractName = 'contract'+Date.now()
  7. // Initialize a smart contract instance
  8. let myContract = chain.ctr.contract(contractName, abi, chain.WASM)

Deploy smart contracts

You can call the new operation to deploy a smart contract.

Request parameters

Parameter Required Type Description
bytecode true string The bytecode of the target smart contract. The bytecode is in the hexadecimal format without the “0x” prefix.
data true object Contains fields such as ‘from’ and ‘parameters’.

Content of the data field

Field Required Type Description
from true string The current account name to be configured.
parameters true Array If the smart contract contains an init() function and this function requires a list of parameters, this list can be passed in through the parameters field.

Examples

  1. java script
  2. const solc = require('@alipay/solc')
  3. const contract = fs.readFileSync('. /CreditManager.sol', {encoding: 'ascii'})
  4. // Set the second parameter to 1 to start compiling
  5. const output = solc.compile(contract, 1)
  6. const abi = JSON.parse(output.contracts[':CreditManager'].interface)
  7. const bytecode = output.contracts[':CreditManager'].bytecode
  8. // Add a timestamp to make sure that the identity of the contract name is unique
  9. const contractName = 'contract'+Date.now()
  10. // Initialize a smart contract instance
  11. let myContract = chain.ctr.contract(contractName, abi)
  12. // Deploy a smart contract. Parameters required by the init() function can be passed in.
  13. myContract.new(bytecode, {
  14. from: 'Tester001',
  15. // parameters: [param1, param2]
  16. }, (err, contract, data) => {
  17. console.log(data)
  18. })

Call smart contracts

Use the name of the target contract method to call the contract method.

Request parameters

Parameter Required Type Description
paramter false Not specified See the parameter list of a specific contract method. The number of parameters varies with the contract method.
data true object Contains the from field.

Content of the data field

Field Required Type Description
from true string The current account name to be configured.

Example 1

Call a contract method when deploying the callback function of the contract:

  1. java script
  2. myContract.new(bytecode, {
  3. from: 'Tester001',
  4. // parameters: [param1, param2]
  5. }, (err, contract, data) => {
  6. console.log(data)
  7. // Two parameters are required when calling the Issue contract method: the account identity and a numerical value.
  8. myContract.Issue('0xc60a9d48105950a0cca07a4c6320b98c303ad42d694a634529e8e1a0a16fcdb5', 100 , { from: 'Tester001' }, (err, output, data) => {
  9. console.log('output is:', output)
  10. })
  11. })

Example 2

Call a contract method after the contract has been deployed. In case of multiple contracts, these contracts are called concurrently. If a call dependency exists, use the callback function.

  1. java script
  2. myContract.new(bytecode, {
  3. from: 'Tester001',
  4. // parameters: [param1, param2]
  5. }, (err, contract, data) => {
  6. console.log(data)
  7. })
  8. // Call the ‘Issue’ contract method
  9. myContract.Issue('0xc60a9d48105950a0cca07a4c6320b98c303ad42d694a634529e8e1a0a16fcdb5', 100 , { from: 'Tester001' }, (err, output, data) => {
  10. console.log('output is:', output)
  11. })

Update smart contracts

You can call the update operation to update a contract that exists on a blockchain. Update smart contracts with caution. The update of contracts needs to be compatible with the data storage of the new contracts and the old contract. Under normal circumstances, we recommend that you do not use this update feature.

Request parameters

Parameter Required Type Description
bytecode true string The bytecode of the target smart contract. The bytecode is in the hexadecimal format without the 0x prefix.
data true object An empty object.

Examples

Call a contract method when deploying the callback function of the contract:

  1. java script
  2. myContract.update(bytecode, {}
  3. , (err, contract, data) => {
  4. console.log('contract update result:', data)
  5. })
Notes: To update the contract, the compiled runtime bytecode is required. This bytecode can be obtained directly by using the --bin-runtime parameter of solc compiler, the Solidity compiler. It is the subset of the bytecode of the compiled --bin parameter. The runtime bytecode can also be obtained by deploying local contracts.

Obtain the runtime bytecode by deploying a contract or using solc-js to update a contract:In JavaScript syntax, solc-js uses the --bin parameter to compile a contract into bytecode by default. This bytecode cannot be used directly to update a contract. However, the runtime bytecode obtained after deploying a contract can be used to update the contract.

Examples

Use solc-js to update smart contracts as follows:

  1. Use solc-js to compile contract A
  2. Deploy smart contract A
  3. Call smart contract A
  4. Modify the smart contract code to obtain smart contract A’
  5. Use solc-js to compile smart contract A’
  6. Deploy the smart contract A’ locally and obtain the runtime bytecode.
  7. Use the A’ runtimebytecode to update smart contract A.
  8. Call smart contract A to verify the update status.
  1. const solc = require('@alipay/solc')
  2. const contract = fs.readFileSync('. /CreditManager.sol', {encoding: 'ascii'})
  3. // Set the second parameter to 1 to start compiling
  4. const output = solc.compile(contract, 1)
  5. const abi = JSON.parse(output.contracts[':CreditManager'].interface)
  6. const bytecode = output.contracts[':CreditManager'].bytecode
  7. console.log('bytecode:', bytecode)
  8. // Add a timestamp to make sure that the identity of the contract name is unique
  9. let contractName = 'contract'+Date.now()
  10. let myContract = chain.ctr.contract(contractName, abi)
  11. // Use the bytecode compiled by solc-js to upgrade contracts
  12. myContract.new(bytecode, {
  13. from: 'Tester001',
  14. }, (err, contract, data) => {
  15. console.log('contract new:', data)
  16. myContract.Issue('0xc60a9d48105950a0cca07a4c6320b98c303ad42d694a634529e8e1a0a16fcdb5', 100 , { from: 'Tester001' }, (err, output, data) => {
  17. console.log('output1 is:', output)
  18. //Change the calculation logic of the contract named CreditManager.sol to obtain a contract named CreditManagerPro.sol. Note that the contract storage definition cannot be changed.
  19. //In the Issue method: change `credit[account] += value;` to `credit[account] += value * 2;`
  20. const contract_pro = fs.readFileSync('. /CreditManagerPro.sol', {encoding: 'ascii'})
  21. // Set the second parameter to 1 to start compiling
  22. const output_pro = solc.compile(contract_pro, 1)
  23. const abi_pro = JSON.parse(output_pro.contracts[':CreditManager'].interface)
  24. const bytecode_pro = output_pro.contracts[':CreditManager'].bytecode
  25. myContract = chain.ctr.contract(contractName, abi_pro)
  26. myContract.new(bytecode_pro, {
  27. from: 'Tester001',
  28. local: true, //Deploy a contract locally to obtain the `runtime` bytecode
  29. block_number: 0 //Use a genesis block to deploy the contract locally to avoid conflict contract IDs.
  30. }, (err, contract, data) => {
  31. console.log('local contract new result:', data)
  32. // Use the obtained `runtime` bytecode to upgrade the contract
  33. myContract.update(data.receipt.output.replace('0x' + chain.EVM, ''), {
  34. }, (err, contract, data) => {
  35. console.log('contract update result:', data)
  36. // Call the updated contract to issue credits
  37. myContract.Issue('0xc60a9d48105950a0cca07a4c6320b98c303ad42d694a634529e8e1a0a16fcdb5', 100 , { from: 'Tester001' }, (err, output, data) => {
  38. console.log('output2 is:', output.toString())
  39. // View the credits that have been issued to the target account. If the contract is updated successfully, the result is 300.
  40. myContract.Query('0xc60a9d48105950a0cca07a4c6320b98c303ad42d694a634529e8e1a0a16fcdb5', { from: 'Tester001' }, (err, output, data) => {
  41. console.log('output3 is:', output.toString())
  42. })
  43. })
  44. })
  45. })
  46. })
  47. })

Results:

  1. ...
  2. contract update result: { msg_type: 63,
  3. sequence: 7,
  4. return_code: 0,
  5. group_id: '0x0000000000000000000000000000000000000000',
  6. receipt:
  7. { result: 0,
  8. gas_used: 28610,
  9. log_entry: [ [Object] ],
  10. output: '' },
  11. block_number: 86114,
  12. transaction_index: 0,
  13. api: 'QueryTransactionReceipt',
  14. txhash:
  15. '0x40a72b99ec64fca0e1cc5025920de086a2523b4761ea5020c0f43a5240dc754a' }
  16. output2 is: true
  17. output3 is: 300