UNPKG

openchain-sdk-yxl-wx-request

Version:

openchain sd YxL wx request

301 lines (257 loc) 7.39 kB
# 智能合约 智能合约模块提供了合约的部署、调用、查询等完整功能支持。 ## 合约部署 ### 创建合约 ```javascript // 创建合约操作 const createContractOperation = { sourceAddress: sourceAddress, // 合约创建者地址 initBalance: '1000000', // 合约初始化余额 type: 0, // 合约类型,0表示JavaScript payload: contractCode, // 合约代码 initInput: 'init-args', // 可选,合约初始化参数 metadata: 'contract info' // 可选,合约备注 }; // 提交创建合约操作 const response = yield sdk.operation.contract.create(createContractOperation); // 获取合约地址 const contractAddress = yield sdk.contract.getAddress({ hash: response.result.hash // 合约创建交易的hash }); ``` ### 合约代码示例 ```javascript // 简单的Token合约示例 'use strict'; const contractCode = ` function init(input) { let params = JSON.parse(input); Chain.store('totalSupply', params.totalSupply); Chain.store('name', params.name); Chain.store('symbol', params.symbol); Chain.store('decimals', params.decimals); Chain.store(Chain.thisAddress, params.totalSupply); } function main(input) { let params = JSON.parse(input); if (params.method === 'transfer') { return transfer(params); } else if (params.method === 'balanceOf') { return balanceOf(params); } throw 'Unknown method'; } function transfer(params) { let from = Chain.thisAddress; let to = params.to; let value = params.value; let fromBalance = Chain.load(from); let toBalance = Chain.load(to) || '0'; if (Number(fromBalance) < Number(value)) { throw 'Insufficient balance'; } Chain.store(from, String(Number(fromBalance) - Number(value))); Chain.store(to, String(Number(toBalance) + Number(value))); return true; } function balanceOf(params) { let address = params.address; let balance = Chain.load(address) || '0'; return balance; } function query(input) { let params = JSON.parse(input); if (params.method === 'balanceOf') { return balanceOf(params); } throw 'Unknown method'; } `; ``` ## 合约调用 ### 通过BU调用合约 ```javascript // 使用调用合约 const invokeByOPOperation = { sourceAddress: sourceAddress, // 调用者地址 contractAddress: contractAddr, // 合约地址 buAmount: '100', // 调用时转入的BU数量 input: JSON.stringify({ // 调用参数 method: 'transfer', to: 'destinationAddress', value: '100' }) }; const buResponse = yield sdk.operation.contract.invokeByBU(invokeByOPOperation); ``` ### 通过资产调用合约 ```javascript // 使用资产调用合约 const invokeByAssetOperation = { sourceAddress: sourceAddress, // 调用者地址 contractAddress: contractAddr, // 合约地址 code: 'CNY', // 资产代码 issuer: 'issuer-address', // 资产发行方地址 assetAmount: '100', // 调用时转入的资产数量 input: JSON.stringify({ // 调用参数 method: 'transfer', to: 'destinationAddress', value: '100' }) }; const assetResponse = yield sdk.operation.contract.invokeByAsset(invokeByAssetOperation); ``` ## 合约查询 ### 查询合约信息 ```javascript // 查询合约基本信息 const contractInfo = yield sdk.contract.getInfo(contractAddress); // 查询合约地址 const contractAddress = yield sdk.contract.getAddress({ hash: contractCreateHash // 合约创建交易的hash }); ``` ### 调用合约查询接口 ```javascript // 调用合约的查询方法 const contractCallResponse = yield sdk.contract.call({ contractAddress: contractAddress, input: JSON.stringify({ method: 'balanceOf', address: 'queryAddress' }) }); ``` ## 合约事件 ### 创建合约日志 ```javascript // 创建合约日志 const createLogOperation = { sourceAddress: sourceAddress, // 日志创建者地址 topic: 'event-topic', // 日志主题 data: 'event-data' // 日志数据 }; const logResponse = yield sdk.operation.log.create(createLogOperation); ``` ### 查询合约日志 ```javascript // 查询合约日志 const logs = yield sdk.operation.log.getEvents({ contractAddress: contractAddress, topic: 'event-topic' }); ``` ## 最佳实践 1. 合约开发规范 ```javascript // 标准合约结构 const standardContract = ` 'use strict'; // 初始化函数 function init(input) { // 验证输入参数 if (!input) throw 'Invalid input'; // 初始化存储 } // 主函数 - 处理所有写操作 function main(input) { // 解析输入 let params = JSON.parse(input); // 方法路由 switch(params.method) { case 'method1': return method1(params); case 'method2': return method2(params); default: throw 'Unknown method'; } } // 查询函数 - 处理只读操作 function query(input) { // 解析输入 let params = JSON.parse(input); // 查询路由 switch(params.method) { case 'query1': return query1(params); case 'query2': return query2(params); default: throw 'Unknown query method'; } } `; ``` 2. 错误处理 ```javascript // 合约中的错误处理 function safeOperation(params) { // 参数验证 if (!params.value || params.value <= 0) { throw 'Invalid value'; } // 状态检查 let state = Chain.load('state'); if (state !== 'active') { throw 'Contract not active'; } // 余额检查 let balance = Chain.load(params.address); if (Number(balance) < Number(params.value)) { throw 'Insufficient balance'; } // 执行操作 try { // 业务逻辑 } catch (e) { throw 'Operation failed: ' + e; } } ``` 3. 存储优化 ```javascript // 优化存储结构 function optimizedStorage() { // 使用前缀区分不同类型的数据 Chain.store('balance:' + address, amount); Chain.store('allowance:' + owner + ':' + spender, amount); // 批量数据使用JSON存储 let data = { key1: value1, key2: value2 }; Chain.store('batch_data', JSON.stringify(data)); } ``` 4. Gas优化 ```javascript // Gas使用优化 function optimizedOperation() { // 减少存储操作 let data = Chain.load('data'); data = JSON.parse(data); data.value += 1; Chain.store('data', JSON.stringify(data)); // 避免循环操作 let total = Chain.load('total'); Chain.store('total', String(Number(total) + value)); } ``` 5. 安全建议 ```javascript // 安全检查示例 function secureOperation(params) { // 权限检查 let owner = Chain.load('owner'); if (Chain.msg.sender !== owner) { throw 'No permission'; } // 数值检查 if (typeof params.value !== 'string' || !/^\d+$/.test(params.value)) { throw 'Invalid number format'; } // 地址验证 if (!Chain.isValidAddress(params.address)) { throw 'Invalid address'; } // 状态检查 if (Chain.load('paused') === 'true') { throw 'Contract is paused'; } } ```