布比区块链JavaScript智能合约是一段JavaScript
代码,代码标准(ECMAScript as specified in ECMA-262)。
本章节旨在为开发者提供如何使用JavaScript编程语言来编写和部署智能合约的指南。介绍基础的编程概念、智能合约的结构,以及如何通过JavaScript与区块链平台交互。
JavaScript智能合约的优点主要包括:
- 广泛的使用基础:JavaScript是世界上使用最广泛的编程语言之一,许多开发者已经熟悉这种语言。这降低了学习成本,使得开发者可以更快地开始编写智能合约。
- 生态系统支持:由于JavaScript的普及,有大量的开发工具、库和框架可以支持智能合约的开发。这包括测试框架、安全工具和其他可以提升开发效率和合约安全的资源。
通过整合这些优势,JavaScript智能合约成为了一个吸引开发者进入区块链领域的有力工具。章节中还会通过示例代码和最佳实践来具体展示如何利用JavaScript的这些优势来构建有效且安全的智能合约。
1. 使用说明
1.1. 介绍
读者对象:本章节主要描述使用JavaScript进行布比区块链合约编写的方法,主要面向于使用JavaScript进行布比区块链的合约开发的开发者。
合约的初始化函数是 init
, 执行的入口函数是 main
函数,查询接口是 query
。这些函数的参数字符串 input
,是调用该合约的时候指定的。
1.2. 示例
下面是一个简单的JavaScript智能合约示例:
"use strict";
function init(input)
{
/*init whatever you want*/
Chain.store('init','initValue');
}
function main(input)
{
let inputObj = JSON.parse(input);
if (inputObj.method === 'save')
{
Chain.store(inputObj.params.key,inputObj.params.value);
return;
}
Utils.assert(true, "Not valid");
}
function query(input)
{
let inputObj = JSON.parse(input);
if (inputObj.method === 'load')
{
let data = Chain.load(inputObj.params.key);
if (data === false) {
return '';
}
return data;
}
Utils.assert(true, "Not valid");
}
1.3. 部署
环境准备
- curl命令行工具或其他能发送http请求的工具,用于http请求;
- 一个节点的http接口访问权限,这里以127.0.0.1:19333为例,实际部署操作时请替换为实际IP端口;
- 一个已经激活的区块链账号私钥,这里以下面账号为例:
- 账号私钥:privbwQsGDqGRYuvkFAEQdS8KWxVTA3ynzMxpwLHTtFsy1eySSPTRCmt;
- 账号地址:adxSdqkc8ooYmthwbiCsNogfyRLH51vh4V75P。
准备工作
查询账号交易序号,使用查询命令:
curl http://127.0.0.1:19333/getAccount?address=adxSdqkc8ooYmthwbiCsNogfyRLH51vh4V75P
结果应该返回error_code为0,然后我们在result字段下查询nonce字段信息,如果在返回结果中没有nonce字段,则代表账号从未发送过交易,表示nonce为0;返回结果示例如下:
{
"error_code" : 0,
"result" : {
"address" : "adxSdqkc8ooYmthwbiCsNogfyRLH51vh4V75P",
"assets" : null,
"assets_hash" : "ad67d57ae19de8068dbcd47282146bd553fe9f684c57c8c114453863ee41abc3",
"balance" : 998989318000,
"metadatas" : null,
"metadatas_hash" : "ad67d57ae19de8068dbcd47282146bd553fe9f684c57c8c114453863ee41abc3",
"nonce" : 1,
"priv" : {
"master_weight" : 1,
"thresholds" : {
"tx_threshold" : 1
}
}
}
}
部署流程
-
准备交易内容模板,将下面的交易内容保存到
tx-deploy-js.json
文件,注意:需要把nonce参数+1,表示账号的下一笔交易;{
"items": [
{
"transaction_json": {
"source_address": "adxSdqkc8ooYmthwbiCsNogfyRLH51vh4V75P",
"nonce": 2,
"fee_limit":1500000000,
"gas_price":1000,
"operations": [{
"type": 1,
"create_account":{
"contract":{
"owner": "adxSdqkc8ooYmthwbiCsNogfyRLH51vh4V75P",
"type": 0,
"payload": ""
},
"init_balance": 10000000,
"init_input" : "",
"priv":{
"master_weight": 0,
"thresholds": {
"tx_threshold": 1
}
}
}
}]
},
"private_keys": ["privbwQsGDqGRYuvkFAEQdS8KWxVTA3ynzMxpwLHTtFsy1eySSPTRCmt"]
}
]
} -
整理交易提交内容,打开 https://jsonformatter.org/json-stringify-online 网站,把JavaScript示例合约内容粘贴在左侧,点击
JSON Stringify
按钮,右侧会生成转义字符串,示例如下:"\"use strict\";\r\nfunction init(input)\r\n{\r\n /*init whatever you want*/\r\n Chain.store('init','initValue');\r\n}\r\n\r\nfunction main(input)\r\n{\r\n let inputObj = JSON.parse(input);\r\n if (inputObj.method === 'save')\r\n {\r\n Chain.store(inputObj.params.key,inputObj.params.value);\r\n return;\r\n }\r\n Utils.assert(true, \"Not valid\");\r\n}\r\n\r\nfunction query(input)\r\n{\r\n let inputObj = JSON.parse(input);\r\n if (inputObj.method === 'load')\r\n {\r\n let data = Chain.load(inputObj.params.key);\r\n if (data === false) {\r\n return '';\r\n }\r\n return data;\r\n }\r\n Utils.assert(true, \"Not valid\");\r\n}"
将上述字符串替换
tx-deploy-js.json
文件中的payload对应的数据部分,然后另存为tx-deploy-js-send.json
文件,替换后的内容示例如下:{
"items": [
{
"transaction_json": {
"source_address": "adxSdqkc8ooYmthwbiCsNogfyRLH51vh4V75P",
"nonce": 2,
"fee_limit":1500000000,
"gas_price":1000,
"operations": [{
"type": 1,
"create_account":{
"contract":{
"owner": "adxSdqkc8ooYmthwbiCsNogfyRLH51vh4V75P",
"type": 0,
"payload": "\"use strict\";\r\nfunction init(input)\r\n{\r\n /*init whatever you want*/\r\n Chain.store('init','initValue');\r\n}\r\n\r\nfunction main(input)\r\n{\r\n let inputObj = JSON.parse(input);\r\n if (inputObj.method === 'save')\r\n {\r\n Chain.store(inputObj.params.key,inputObj.params.value);\r\n return;\r\n }\r\n Utils.assert(true, \"Not valid\");\r\n}\r\n\r\nfunction query(input)\r\n{\r\n let inputObj = JSON.parse(input);\r\n if (inputObj.method === 'load')\r\n {\r\n let data = Chain.load(inputObj.params.key);\r\n if (data === false) {\r\n return '';\r\n }\r\n return data;\r\n }\r\n Utils.assert(true, \"Not valid\");\r\n}"
},
"init_balance": 10000000,
"init_input" : "",
"priv":{
"master_weight": 0,
"thresholds": {
"tx_threshold": 1
}
}
}
}]
},
"private_keys": ["privbwQsGDqGRYuvkFAEQdS8KWxVTA3ynzMxpwLHTtFsy1eySSPTRCmt"]
}
]
}提交交易,把上一步整理好的
tx-deploy-js-send.json
文件作为POST请求的参数提交到节点:curl -X "POST" --data-binary "@tx-deploy-js-send.json" http://127.0.0.1:19333/submitTransaction
示例返回:
{
"results" : [
{
"error_code" : 0,
"error_desc" : "",
"hash" : "1b9eb37d9a4047381feffe04795eadc391bec9f719e1f9016d551a6cd5a109d3"
}
],
"success_count" : 1
}提交成功返回交易交易
1b9eb37d9a4047381feffe04795eadc391bec9f719e1f9016d551a6cd5a109d3
。 -
查询交易状态,向节点提交交易查询请求:
curl http://127.0.0.1:19333/getTransactionHistory?hash=1b9eb37d9a4047381feffe04795eadc391bec9f719e1f9016d551a6cd5a109d3
示例返回:
{"error_code":0,"result":{"total_count":1,"transactions":[{"actual_fee":1001062000,"close_time":1712752134736008,"error_code":0,"error_desc":"[{\"contract_address\":\"adxSTDkyymx2aumaG167ma1YdPtxgorVe5mxx\",\"contract_evm_address\":\"0x01fc7e852ae563cab387bf7034a16f04891b0ddc\",\"operation_index\":0}]","hash":"1b9eb37d9a4047381feffe04795eadc391bec9f719e1f9016d551a6cd5a109d3","ledger_seq":201,"signatures":[{"public_key":"b0011ced68075723ec3bd5db6f7fb4faba33f00f33e374a53806253160bc8f708e8933530369","sign_data":"cb4ca805c14ec7ce2d263f396e0b8280beeedfeada9c057cb3ed067c506f14b444a33cd79a396201f3601f8439178d454955ace0bd1a214433b90d62f871e903"},{"public_key":"b00132c3d1244e0be4d711fb12d5b3d24abeb60f11e8c61c5efe28ad20b793d7fb2402f819e9","sign_data":"79bcd021d90d2411779814311c6927ede6a83bc70f61971ad81f3f3a9581eea924fade599f94fa6dfad7c614ed252c97e5163b2f5877226d8f5f973de5ad3101"}],"transaction":{"fee_limit":1500000000,"gas_price":1000,"nonce":2,"operations":[{"create_account":{"contract":{"owner":"adxSdqkc8ooYmthwbiCsNogfyRLH51vh4V75P","payload":"\"use strict\";\r\nfunction init(input)\r\n{\r\n /*init whatever you want*/\r\n Chain.store('init','initValue');\r\n}\r\n\r\nfunction main(input)\r\n{\r\n let inputObj = JSON.parse(input);\r\n if (inputObj.method === 'save')\r\n {\r\n Chain.store(inputObj.params.key,inputObj.params.value);\r\n return;\r\n }\r\n Utils.assert(true, \"Not valid\");\r\n}\r\n\r\nfunction query(input)\r\n{\r\n let inputObj = JSON.parse(input);\r\n if (inputObj.method === 'load')\r\n {\r\n let data = Chain.load(inputObj.params.key);\r\n if (data === false) {\r\n return '';\r\n }\r\n return data;\r\n }\r\n Utils.assert(true, \"Not valid\");\r\n}"},"init_balance":10000000,"priv":{"thresholds":{"tx_threshold":1}}},"type":1}],"source_address":"adxSdqkc8ooYmthwbiCsNogfyRLH51vh4V75P"},"tx_size":1062}]}}
交易执行成功的话,可以在error_desc下的contract_address字段找到新创建的合约账号地址
adxSTDkyymx2aumaG167ma1YdPtxgorVe5mxx
,实际的合约地址以实际交易返回结果为准。
1.4. 调用
前置条件
- curl命令行工具,用于http请求;
- 一个节点的http接口访问权限,这里以127.0.0.1:19333为例,实际部署操作时请替换为实际IP端口;
- 一个已经激活的区块链账号私钥,这里以下面账号为例:
- 账号私钥:privbwQsGDqGRYuvkFAEQdS8KWxVTA3ynzMxpwLHTtFsy1eySSPTRCmt;
- 账号地址:adxSdqkc8ooYmthwbiCsNogfyRLH51vh4V75P。
准备工作
查询账号交易序号,使用查询命令:
curl http://127.0.0.1:19333/getAccount?address=adxSdqkc8ooYmthwbiCsNogfyRLH51vh4V75P
结果应该返回error_code为0,然后我们在result字段下查询nonce字段信息,如果在返回结果中没有nonce字段,则代表账号从未发送过交易,表示nonce为0;返回结果示例如下:
{
"error_code" : 0,
"result" : {
"address" : "adxSdqkc8ooYmthwbiCsNogfyRLH51vh4V75P",
"assets" : null,
"assets_hash" : "ad67d57ae19de8068dbcd47282146bd553fe9f684c57c8c114453863ee41abc3",
"balance" : 997978256000,
"metadatas" : null,
"metadatas_hash" : "ad67d57ae19de8068dbcd47282146bd553fe9f684c57c8c114453863ee41abc3",
"nonce" : 2,
"priv" : {
"master_weight" : 1,
"thresholds" : {
"tx_threshold" : 1
}
}
}
}
调用流程
-
准备合约调用参数
{
"method":"save",
"params":{
"key":"testKey",
"value":"testValue"
}
}打开 https://www.json.cn/jsonzip/ 网站, 把上述调用参数复制到输入框中,点击
压缩并转义
,生成如下 字符串:{\"method\":\"save\",\"params\":{\"key\":\"testKey\",\"value\":\"testValue\"}}
-
准备交易内容,上一步得到的调用参数填入input参数字段,将下面的交易内容保存到
tx-call-js.json
文件,注意:需要把nonce参数+1,表示账号的下一笔交易;{
"items": [
{
"transaction_json": {
"source_address": "adxSdqkc8ooYmthwbiCsNogfyRLH51vh4V75P",
"nonce": 3,
"fee_limit":1500000000,
"gas_price":1000,
"operations": [{
"pay_coin": {
"amount": 0,
"dest_address": "adxSTDkyymx2aumaG167ma1YdPtxgorVe5mxx",
"input": "{\"method\":\"save\",\"params\":{\"key\":\"testKey\",\"value\":\"testValue\"}}"
},
"type": 7
}]
},
"private_keys": ["privbwQsGDqGRYuvkFAEQdS8KWxVTA3ynzMxpwLHTtFsy1eySSPTRCmt"]
}
]
} -
提交交易,把上一步整理好的
tx-call-js.json
文件作为POST请求的参数提交到节点curl -X "POST" --data-binary "@tx-call-js.json" http://127.0.0.1:19333/submitTransaction
示例返回:
{
"results" : [
{
"error_code" : 0,
"error_desc" : "",
"hash" : "21adbf23961c49858fd344317eaf788d11366682e752ef81ce58dfe12fe75f1c"
}
],
"success_count" : 1
}提交成功返回交易交易
21adbf23961c49858fd344317eaf788d11366682e752ef81ce58dfe12fe75f1c
。 -
查询交易状态,向节点提交交易查询请求:
curl http://127.0.0.1:19333/getTransactionHistory?hash=21adbf23961c49858fd344317eaf788d11366682e752ef81ce58dfe12fe75f1c
示例返回:
{"error_code":0,"result":{"total_count":1,"transactions":[{"actual_fee":458000,"close_time":1712754893172708,"error_code":0,"error_desc":"","hash":"21adbf23961c49858fd344317eaf788d11366682e752ef81ce58dfe12fe75f1c","ledger_seq":247,"signatures":[{"public_key":"b0011ced68075723ec3bd5db6f7fb4faba33f00f33e374a53806253160bc8f708e8933530369","sign_data":"7e5d2ae975faf43bd0f18240230a95eac068e7032ae13e62bc4a710d3ab2d6f08699d6cdf533aebafd93a2ff8da6db330c5eb45d6db627988a750066c0e7a104"},{"public_key":"b00132c3d1244e0be4d711fb12d5b3d24abeb60f11e8c61c5efe28ad20b793d7fb2402f819e9","sign_data":"ac942a193c5e57b35c9fc1460b920d6c042a1687539b6227ebf3f2885086940bda25ecff7bdefbefd9cd5472744041118046a293da73398187804d15d72d2003"}],"transaction":{"fee_limit":1500000000,"gas_price":1000,"nonce":3,"operations":[{"pay_coin":{"dest_address":"adxSTDkyymx2aumaG167ma1YdPtxgorVe5mxx","input":"{\"method\":\"save\",\"params\":{\"key\":\"testKey\",\"value\":\"testValue\"}}"},"type":7}],"source_address":"adxSdqkc8ooYmthwbiCsNogfyRLH51vh4V75P"},"tx_size":458}]}}
交易执行成功的话,返回数据的error_code应该为0。
1.5. 查询
前置条件
- curl命令行工具,用于http请求;
- 一个节点的http接口访问权限,这里以127.0.0.1:19333为例,实际部署操作时请替换为实际IP端口;
查询流程
-
准备合约查询参数
{
"method":"load",
"params":{
"key":"testKey"
}
}打开 https://www.json.cn/jsonzip/ 网站, 把上述调用参数复制到输入框中,点击
压缩并转义
,生成如下字符串:{\"method\":\"load\",\"params\":{\"key\":\"testKey\"}}
-
准备参数内容模板,上一步得到的合约查询参数填入input字段,将下面的交易内容保存到
tx-query-js.json
文件;{
"contract_address" : "adxSTDkyymx2aumaG167ma1YdPtxgorVe5mxx",
"code" : "",
"input" : "{\"method\":\"load\",\"params\":{\"key\":\"testKey\"}}",
"contract_balance" : "0",
"fee_limit" : 100000000000000000,
"gas_price": 1000,
"opt_type" : 2,
"source_address" : ""
} -
提交交易,把上一步整理好的
tx-query-js.json
文件作为POST请求的参数提交到节点curl -X "POST" --data-binary "@tx-query-js.json" http://127.0.0.1:19333/callContract
返回结果示例:
{
"error_code" : 0,
"error_desc" : "",
"result" : {
"logs" : {
"0-adxSTDkyymx2aumaG167ma1YdPtxgorVe5mxx" : null
},
"query_rets" : [
{
"result" : {
"type" : "string",
"value" : "testValue"
}
}
],
"stat" : {
"apply_time" : 2012,
"memory_usage" : 1832920,
"stack_usage" : 16,
"step" : 109
},
"txs" : null
}
}调用合约返回的数据在query_rets字段下。
2. 语法介绍
2.1. 接口对象
布比区块链智能合约内提供了全局对象 Chain
和 Utils
, 这两个对象提供了多样的方法和变量,可以获取区块链的一些信息,也可驱动账号发起所有交易,除了设置门限和权重这两种类型的操作。
注意,自定义的变量不要与内置对象重复,否则会造成不可控的数据错误。
使用方法如下:
对象.方法(变量)
示例:
- 获取账号余额:
Chain.getBalance('adxSZ7HNR1Nk8D8wm6pkcWNb6rnMZncyTVHSb');
- 打印日志:
Utils.log('hello');
- 当前区块号:
Chain.block.number;
读写权限:
对象里的每个函数都有固定的只读或者可写权限
只读权限是指不会写数据到区块链的接口函数,比如获取余 额 Chain.getBalance
可写权限是指会写数据到区块链的接口函数,比如转账 Chain.payCoin
在编写智能合约的时候,需要注意的是不同的入口函数拥有不同的调用权限
init
和 main
能调用所有的内置函数
query
只能调用只读权限的函数,否则在调试或者执行过程中会提示接口未定义
返回值介绍:
所有内部函数的调用,如果失败则返回 false 或者直接抛出异常执行终止,成功则为其他对象。如果遇到参数错误,会在错误描述中提示参数位置出错,这里的位置指参数的索引号,即从 0 开始计数。例如 parameter 1
表示第 2 个参数错误。如下例子:
Chain.issueAsset("CNY", 10000);
/*
错误描述:
Contract execute error,issueAsset parameter 1 should be a string
指第 2 个参数应该为字符串
*/
2.2. 异常处理
-
JavaScript异常
当合约运行中出现未捕获的JavaScript异常时,处理规定:
- 本次合约执行失败,合约中做的所有交易都不会生效。
- 触发本次合约的这笔交易为失败。错误代码为
151
。
-
执行交易失败
合约中可以执行多个交 易,只要有一个交易失败,就会抛出异常,导致整个交易失败
3. 合约API
3.1. Chain.load
获取合约账号的metadata信息
Chain.load(metadata_key);
- metadata_key: metadata的key
let value = Chain.load('abc');
/*
权限:只读
返回:成功返回字符串,如 'values', 失败返回false
*/
即可得到本合约账号中自定数据的abc的值
3.2. Chain.store
存储合约账号的metadata信息
Chain.store(metadata_key, metadata_value);
- metadata_key: metadata 的 key
- metadata_key: metadata 的 value
Chain.store('abc', 'values');
/*
权限:可写
返回:成功返回true, 失败抛异常
*/
3.3. Chain.del
删除合约账号的metadata信息
Chain.del(metadata_key);
- metadata_key: metadata的key
Chain.del('abc');
/*
权限:可写
返回:成功返回true, 失败抛异常
*/
即可删除本合约账号中自定数据的abc的值
3.4. Chain.getBlockHash
获取区块信息
Chain.getBlockHash(offset_seq);
-
offset_seq: 距离最后一个区块的偏移量,范围:[0,1024)
例如
let ledger = Chain.getBlockHash(4);
/*
权限:只读
返回:成功返回字符串,如 'c2f6892eb934d56076a49f8b01aeb3f635df3d51aaed04ca521da3494451afb3',失败返回 false
*/
3.5. Chain.tlog
输出交易日志
Chain.tlog(topic,args...);
-
tlog会产生一笔交易写在区块上
-
topic: 日志主题,必须为字符串类型,参数长度(0,128]
-
args...: 最多可以包含5个参数,参数类型可 以是字符串、数值或者布尔类型,每个参数长度(0,1024]
例如
Chain.tlog('transfer',sender +' transfer 1000',true);
/*
权限:可写
返回:成功返回 true,失败抛异常
*/
3.6. Chain.getAccountMetadata
获取指定账号的metadata
Chain.getAccountMetadata(account_address, metadata_key);
-
account_address: 账号地址
-
metadata_key: metadata的key
例如
let value = Chain.getAccountMetadata('adxSZ7HNR1Nk8D8wm6pkcWNb6rnMZncyTVHSb', 'abc');
/*
权限:只读
返回:成功返回字符串,如 'values', 失败返回false
*/
3.7. Chain.getBalance
获取账号coin amount
Chain.getBalance(address);
-
address: 账号地址
例如
let balance = Chain.getBalance('adxSZ7HNR1Nk8D8wm6pkcWNb6rnMZncyTVHSb');
/*
权限:只读
返回:字符串格式数字 '9999111100000'
*/
3.8. Chain.getAccountAsset
获取某个账号的资产信息
Chain.getAccountAsset(account_address, asset_key);
-
account_address: 账号地址
-
asset_key: 资产属性
例如
let asset_key =
{
'issuer' : 'adxSZ7HNR1Nk8D8wm6pkcWNb6rnMZncyTVHSb',
'code' : 'CNY'
};
let bar = Chain.getAccountAsset('adxSZ7HNR1Nk8D8wm6pkcWNb6rnMZncyTVHSb', asset_key);
/*
权限:只读
返回:成功返回资产数字如'10000',失败返回 false
*/
3.9. Chain.getAccountPrivilege
获取某个账号的权限信息
Chain.getAccountPrivilege(account_address);
-
account_address: 账号地址
例如
let privilege = Chain.getAccountPrivilege('adxSZ7HNR1Nk8D8wm6pkcWNb6rnMZncyTVHSb');
/*
权限:只读
返回:成功返回权限json字符串如'{"master_weight":1,"thresholds":{"tx_threshold":1}}',失败返回 falses
*/
3.10. Chain.getContractProperty
获取合约账号属性
Chain.getContractProperty(contract_address);
-
contract_address: 合约地址
例如
let value = Chain.getContractProperty('adxSonEfJM33jCpLHru87dcfeRfB9kdqdzzat');
/*
权限:只读
返回:成功返回JSON对象,如 {"type":0, "length" : 416}, type 指合约类型, length 指合约代码长度,如果该账户不是合约则,length 为0.
失败返回false
*/
3.11. Chain.payCoin
转账
Chain.payCoin(address, amount[, input], [, metadata]);
-
address: 发送Gas的目标地址
-
amount: 发送Gas的数量
-
input: 可选,合约参数,如果用户未填入,默认为空字符串
-
metadata: 可选,转账备注,调用
GET /getTransactionHistory
方法查询交易结果时,显示为十六进制字符串,需要转换为明文。注意,如果提供metadata参数,那么也必须提供input参数,否则内置接口无法区分该参数是 谁,因为两者都是可选的。如果没有input,可以传入空字符串""占位,以防止内置接口将metadata参数误认为inut参数。
例如
Chain.payCoin("adxSZ7HNR1Nk8D8wm6pkcWNb6rnMZncyTVHSb", "10000", "", "vote reward");
/*
权限:可写
返回:成功返回 true,失败抛异常
*/
3.12. Chain.issueAsset
发行资产
Chain.issueAsset(code, amount);
-
code: 资产代码
-
amount: 发行资产数量
例如
Chain.issueAsset("CNY", "10000");
/*
权限:可写
返回:成功返回 true,失败抛异常
*/
3.13. Chain.payAsset
转移资产
Chain.payAsset(address, issuer, code, amount[, input]);
-
address: 转移资产的目标地址
-
issuer: 资产发行方
-
code: 资产代码
-
amount: 转移资产的数量
-
input: 可选,合约参数,如果用户未填入,默认为空字符串
-
metadata: 可选,转账备注,调用
GET /getTransactionHistory
方法查询交易结果时,显示为十六进制字符串,需要转换为明文。注意,如果提供metadata参数,那么也必须提供input参数,否则内置接口无法区分该参数是谁,因为两者都是可选的。如果不需要input,可以传入空字符串""占位,以防止内置接口将metadata参数误认为inut参数。
例如
Chain.payAsset("adxSZ7HNR1Nk8D8wm6pkcWNb6rnMZncyTVHSb", "adxSio3m7C7D84GzgmtTXanUNMwPezys9azQB", "CNY", "10000", "", "Trading certificate");
/*
权限:可写
返回:成功返回 true,失败抛异常
*/
3.14. Chain.delegateCall
委托调用
Chain.delegateCall(contractAddress, input);
-
contractAddress: 被调用的合约地址。
-
input:调用参数。
Chain.delegateCall 函数会触发 被调用的合约main函数入口,并且把当前合约的执行环境赋予被调用的合约。如合约A委托调用合约B,即执行B(main入口)的代码,读写A的数据。
例如
let ret = Chain.delegateCall('adxSd6Qg8UFayWWuzLjMwJUt6f7oTz5GJEjDj','{}');
/*
权限:可写
返回:成功会返回被委托者合约main函数执行的结果,失败抛出异常
*/
3.15. Chain.delegateQuery
委托查询
Chain.delegateQuery(contractAddress, input);
-
contractAddress: 被调用的合约地址。
-
input:调用参数。
Chain.delegateQuery 函数会触发被调用的合约query函数入口,且把当前合约的执行环境赋予被调用的合约。如合约A委托查询合约B,即执行B(query入口)的代码,读取A的数据。
例如
let ret = Chain.delegateQuery('adxSd6Qg8UFayWWuzLjMwJUt6f7oTz5GJEjDj',"");
/*
权限:只读
返回:调用成功则返回JSON对象 {"result":"4"},其中 result 字段的值即查询的具体结果,调用失败返回JSON对象 {"error":true} 。
*/
3.16. Chain.contractCall
调用合约
Chain.contractCall(contractAddress, asset, amount, input);
-
contractAddress: 被调用的合约地址。
-
asset : 资产类别,true代表Gas,对象
{"issue": adxxxx, "code" : USDT}
代表资产。 -
amount: 资产数量。
-
input:调用参数。
Chain.contractCall 函数会触发被调用的合约main函数入口。
例如
let ret = Chain.contractCall('adxSd6Qg8UFayWWuzLjMwJUt6f7oTz5GJEjDj',true, toBaseUnit("10"), "");
/*
权限:可写
返回:如果目标账户为普通账户,则返回true,如果目标账户为合约,成功会返回被委托者合约main函数执行的结果,调用失败则抛出异常
*/
3.17. Chain.contractQuery
查询合约
Chain.contractQuery(contractAddress, input);
-
contractAddress: 被调用的合约地址。
-
input:调用参数。
Chain.contractQuery 会调用合约的查询接口
例如
let ret = Chain.contractQuery('adxSd6Qg8UFayWWuzLjMwJUt6f7oTz5GJEjDj',"");
/*
权限:只读
返回:调用成功则返回JSON对象 {"result":"xxx"},其中 result 字段的值即查询的具体结果,调用失败返回JSON对象 {"error":true}。
*/
3.18. Chain.contractCreate
创建合约
Chain.contractCreate(balance, type, code, input);
-
balance: 字符串类型,转移给被创建的合约的资产。
-
type : 整型,0代表javascript。
-
code: 字符串类型, 合约代码。
-
input:init函数初始化参数。
Chain.contractCreate 创建合约。