🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 开发示例 加载合约需要通过合约地址进行加载,内置注册合约一般有指定的固定地址,其它业务合约需要先通过这个注册合约查找到对应的合约地址,再进行加载。 1.引入`web3`,`key-manager`: ```js //node环境 var Web3 = require('web3'); var key= require('key-manager'); ``` 2.创建钱包: 创建好钱包文件后,需要自行保存这个钱包文件!对于底层链来说,一个钱包就是一个用户,后续用户需要使用这个钱包文件调用合约进行业务操作,保存到本地方便用户备份。 ```js // 创建钱包文件 let password='123456', keyObject=null; key.createKey('account', 'username', password, function(err, data) { keyObject=data; }); ``` 3.获取key的私钥: ```js // 获取key的私钥 let privateKey=''; key.recover(password, keyObject, function(err, data){ privateKey=data; }); ``` 4.设置节点json-rpc请求地址: ```js if (typeof web3 !== 'undefined') { web3 = new Web3(web3.currentProvider); } else { // set the provider you want from Web3.providers web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:6789")); } ``` 5.加载注册合约: 加载合约需要通过合约地址进行加载,内置注册合约一般有指定的固定地址,其它业务合约需要先通过这个注册合约查找到对应的合约地址,再进行加载。 ```js //内置合约abi,地址 const DEFAULT_ABI =[{ "constant": false, "inputs": [{ "name": "_moduleName", "type": "string" }, { "name": "_moduleVersion", "type": "string" }, { "name": "_contractName", "type": "string" }, { "name": "_contractVersion", "type": "string" }], "name": "register", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "type": "function" }, { "constant": true, "inputs": [{ "name": "_addr", "type": "address" }], "name": "findModuleNameByAddress", "outputs": [{ "name": "_moduleName", "type": "uint256" }], "payable": false, "type": "function" }, { "constant": true, "inputs": [{ "name": "_contractAddr", "type": "address" }], "name": "IfContractRegist", "outputs": [{ "name": "", "type": "bool" }], "payable": false, "type": "function" }, { "constant": false, "inputs": [], "name": "unRegister", "outputs": [], "payable": false, "type": "function" }, { "constant": true, "inputs": [{ "name": "_moduleName", "type": "string" }, { "name": "_moduleVersion", "type": "string" }], "name": "IfModuleRegist", "outputs": [{ "name": "", "type": "bool" }], "payable": false, "type": "function" }, { "constant": true, "inputs": [{ "name": "_moduleName", "type": "string" }, { "name": "_moduleVersion", "type": "string" }], "name": "getModuleAddress", "outputs": [{ "name": "_address", "type": "address" }], "payable": false, "type": "function" }, { "constant": false, "inputs": [{ "name": "_fromModuleNameAndVersion", "type": "string" }, { "name": "_fromNameAndVersion", "type": "string" }, { "name": "_toModuleNameAndVersion", "type": "string" }, { "name": "_toNameAndVersion", "type": "string" }, { "name": "_signString", "type": "string" }], "name": "transferContract", "outputs": [{ "name": "_errno", "type": "uint256" }], "payable": false, "type": "function" }, { "constant": true, "inputs": [{ "name": "_moduleName", "type": "string" }, { "name": "_moduleVersion", "type": "string" }, { "name": "_contractName", "type": "string" }, { "name": "_contractVersion", "type": "string" }], "name": "IfContractRegist", "outputs": [{ "name": "", "type": "bool" }], "payable": false, "type": "function" }, { "constant": false, "inputs": [{ "name": "_moduleName", "type": "string" }, { "name": "_moduleVersion", "type": "string" }, { "name": "_newOwner", "type": "address" }], "name": "changeModuleRegisterOwner", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "type": "function" }, { "constant": false, "inputs": [{ "name": "_moduleName", "type": "string" }, { "name": "_moduleVersion", "type": "string" }], "name": "register", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "type": "function" }, { "constant": true, "inputs": [{ "name": "_addr", "type": "address" }], "name": "findContractVersionByAddress", "outputs": [{ "name": "_contractVersion", "type": "uint256" }], "payable": false, "type": "function" }, { "constant": true, "inputs": [{ "name": "_addr", "type": "address" }], "name": "findResNameByAddress", "outputs": [{ "name": "_contractName", "type": "uint256" }], "payable": false, "type": "function" }, { "constant": false, "inputs": [{ "name": "_moduleName", "type": "string" }, { "name": "_moduleVersion", "type": "string" }, { "name": "_contractName", "type": "string" }, { "name": "_contractVersion", "type": "string" }, { "name": "_newOwner", "type": "address" }], "name": "changeContractRegisterOwner", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "type": "function" }, { "constant": true, "inputs": [{ "name": "_moduleName", "type": "string" }, { "name": "_moduleVersion", "type": "string" }, { "name": "_contractName", "type": "string" }, { "name": "_contractVersion", "type": "string" }], "name": "getContractAddress", "outputs": [{ "name": "_address", "type": "address" }], "payable": false, "type": "function" }, { "constant": true, "inputs": [{ "name": "_addr", "type": "address" }], "name": "findModuleVersionByAddress", "outputs": [{ "name": "_moduleVersion", "type": "uint256" }], "payable": false, "type": "function" }, { "constant": true, "inputs": [{ "name": "_pageNum", "type": "uint256" }, { "name": "_pageSize", "type": "uint256" }], "name": "getRegisteredContract", "outputs": [{ "name": "_json", "type": "string" }], "payable": false, "type": "function" }, { "constant": true, "inputs": [{ "name": "_moduleAddr", "type": "address" }], "name": "IfModuleRegist", "outputs": [{ "name": "", "type": "bool" }], "payable": false, "type": "function" }, { "inputs": [], "payable": false, "type": "constructor" }], DEFAULT_ADDRESS = '0x0000000000000000000000000000000000000011'; let REGContract = this.web3.eth.contract(DEFAULT_ABI), registerManager = REGContract.at(DEFAULT_ADDRESS); ``` 6.加载业务合约: ```js let contractName='UserManager',//合约名 来源:合约开发文档/合约代码 contractVersion='0.0.1.0',//合约版本 来源:合约开发 moduleName='SystemModuleManager',//模块名字 来源:合约开发 moduleVersion='0.0.1.0';//模块版本 来源:合约开发 //通过合约名、合约版本、模块名、模块版本获取合约地址 let queryAddress = registerManager.getContractAddress.call(moduleName, moduleVersion, contractName, contractVersion); //获取合约 let contract = this.web3.eth.contract(ABI), userManager = contract.at(queryAddress); ``` 7.调用合约的业务方法: 合约加载成功后,则可以直接调用合约业务方法,合约业务方法分为交易类型和非交易类型;交易类型一般是增,删,改业务,需要交易签名,我们调用此类业务方法时,Web3j的RawTransactionManager会进行交易打包签名,而非交易类型的方法一般是查询类的业务,这个不需要交易签名。 例如:调用上述RegisterApplyManager合约新增用户业务方法(交易类型) ```js EthereumTx = require('ethereumjs-tx'); const data = userManager.getData([contructorParam1] [, contructorParam2]), txParams = { //from就是钱包地址,但是用私钥签名后,钱包地址可以通过签名得到公钥再通过公钥得到钱包地址 不用传 //from: '0x5fd205613e71810387265e7505997c69c27f9ae9', //防重 每次都生成一个新的nonce,用过之后就失效了 nonce: web3.nonce(), gasPrice: 21000000000, gasLimit: 843314949521407, to: userManager.address, value: 0, data: data, }, tx = new EthereumTx(txParams); //用私钥给数据签名 let privateKey = Buffer.from(privateKey, 'hex'); tx.sign(privateKey); const serializedTx = tx.serialize(); let serializedTxHex = "0x" + serializedTx.toString('hex'); //发送一个已经签名的交易 let hash = web3.eth.sendRawTransaction(serializedTxHex); //通过一个交易哈希,获取一个交易的收据。 let result=web3.eth.getTransactionReceipt(hash); console.log(result); ``` 调用上述UserManager合约查找用户信息业务方法(非交易类型) ```js let result = userManager.findByUuid(uuid); //输出结果 console.log(result) ```