0.本地文件夹 安装 npm install solc web3 fc
0.5 运行testrpc
1. 首先要有一个合约要不输,比如如下合约,保存为文件Token.sol:
pragma solidity ^0.4.0;
contract Token {
mapping (address => uint) public balances;
function Token() {
balances[msg.sender] = 1000000;
}
function transfer(address _to, uint _amount) {
if (balances[msg.sender] < _amount) {
throw;
}
balances[msg.sender] -= _amount;
balances[_to] += _amount;
}
}
2. 用js部署
const fs = require('fs');
const solc = require('solc');
const Web3 = require('web3');
const async = require('async');
const ethabi = require('ethereumjs-abi');
web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
input = fs.readFileSync('Token.sol');
output = solc.compile(input.toString(), 1);
bytecode = output.contracts[':Token'].bytecode;
abi = JSON.parse(output.contracts['Token'].interface);
function deploy(web3, compiledContract, args, gas, address, sendImmediately) {
abi = JSON.parse(compiledContract.interface);
bytecode = compiledContract.bytecode;
if (args.length > 0) {
constructTypes = abi
.filter(x => x.type === 'constructor')[0]
.inputs.map(x => x.type);
abiEncoded = ethabi.rawEncode(constructTypes, args);
console.log(`ABI encoded constructor arguments: ${abiEncoded.toString('hex')}`);
}
contract = web3.eth.contract(abi);
data = `0x${contract.new.getData.apply(null, args.concat({ data: bytecode }))}`;
if (gas && address && sendImmediately) {
web3.eth.sendTransaction({ from: address, gas, data }, (err, txHash) => {
if (err) {
console.log('err1:', err);
} else {
let contractAddress;
async.whilst(
() => !contractAddress,
(callback) => {
web3.eth.getTransactionReceipt(txHash, (errReceipt, result) => {
if (result && result.contractAddress) contractAddress = result.contractAddress;
setTimeout(() => {
callback(null);
}, 10 * 1000);
});
},
(errWhilst) => {
if (!errWhilst) {
console.log(contractAddress);
} else {
console.log('err2:', err);
console.log(err);
}
},
);
}
});
} else {
console.log('Contract data:', data);
}
}
solidityFile = './Token.sol'
contractName = 'Token';
solcVersion = 'v0.4.9+commit.364da425';
address = web3.eth.coinbase;
admin = address;
feeAccount = address;
accountLevelsAddr = 0;
feeMake = 0;
feeTake = 3000000000000000;
feeRebate = 0;
gas = 2000000;
args = [admin, feeAccount, accountLevelsAddr, feeMake, feeTake, feeRebate];
solc.loadRemoteVersion(solcVersion, (err, solcV) => {
console.log('Solc version:', solcV.version());/第一遍到这里可能失败,第二次就过去了
fs.readFile(solidityFile, (errRead, result) => {
source = result.toString();
output = solcV.compile(source, 1); // 1 activates the optimiser
if (output.errors) console.log(output.errors);
sendImmediately = true;
deploy(web3, output.contracts[`:${contractName}`], args, gas, address, sendImmediately);//过一会打印部署的合约地址
});
});
3.通过abi 接口调用智能合约
得到abi字符串:https://chriseth.github.io/browser-solidity/#version=soljson-latest.js
或者 solcjs --abi --bin ./token.sol -o .
abi = JSON.parse('[{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balances","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]')
tokenContract = web3.eth.contract(abi)
tokenContract = tokenContract.at('0x35877aa1a91a936c52571dad91213fca6b49789f')
tokenContract.balances(web3.eth.coinbase[0])
tokenContract.transfer(web3.eth.accounts[1], 222, {from: web3.eth.accounts[0]})
faq:出错处理:
1. gTypeError: Cannot read property 'interface' of undefined
at deploy (repl:2:43)
at fs.readFile (repl:10:7)
at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:528:3)
deploy(web3, output.contracts[`:${contractName}`], args, gas, address, sendImmediately);这里的名称有问题
2.tokenContract.transfer(web3.eth.accounts[3], 999);
Error: invalid address
at inputAddressFormatter (/home/sam/ethereum/web3.js/example/node_modules/web3/lib/web3/formatters.js:271:11)
at inputTransactionFormatter (/home/sam/ethereum/web3.js/example/node_modules/web3/lib/web3/formatters.js:97:20)
at /home/sam/ethereum/web3.js/example/node_modules/web3/lib/web3/method.js:89:28
at Array.map (
at Method.formatInput (/home/sam/ethereum/web3.js/example/node_modules/web3/lib/web3/method.js:88:32)
at Method.toPayload (/home/sam/ethereum/web3.js/example/node_modules/web3/lib/web3/method.js:114:23)
at Eth.send [as sendTransaction] (/home/sam/ethereum/web3.js/example/node_modules/web3/lib/web3/method.js:139:30)
at SolidityFunction.sendTransaction (/home/sam/ethereum/web3.js/example/node_modules/web3/lib/web3/function.js:133:26)
at SolidityFunction.execute (/home/sam/ethereum/web3.js/example/node_modules/web3/lib/web3/function.js:219:37)
要指定参数:tokenContract.transfer(web3.eth.accounts[4], 999, {from:web3.eth.accounts[3]});