## 开发示例
加载合约需要通过合约地址进行加载,内置注册合约一般有指定的固定地址,其它业务合约需要先通过这个注册合约查找到对应的合约地址,再进行加载。
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)
```