一、安装Truffle
sudo npm install -g truffle
二、初始化Truffle
sudo mkdir /Project/SmartToken
cd /Project/SmartToken
truffle init
初始化的目录结构如下
|____contracts
| |____Migrations.sol
|____migrations
| |____1_initial_migration.js
|____test
|____truffle.js
contracts 存放需要部署的智能合约,migration是部署代码,指定需要将哪些合约部署上区块链,truffle.js标识通过本地哪个端口的区块链来部署。
三、修改合约
在contract目录下创建SmartToken.sol文件,写入合约
pragma solidity ^0.5.0;
contract SmartToken {
mapping(address => uint) tokens;
event OnValueChanged(address indexed _from, uint _value);
function depositToken(address recipient, uint value) public returns (bool success) {
tokens[recipient] += value;
emit OnValueChanged(recipient, tokens[recipient]);
return true;
}
function withdrawToken(address recipient, uint value) public returns (bool success) {
if (int(tokens[recipient] - value) < 0) {
tokens[recipient] = 0;
} else {
tokens[recipient] -= value;
}
emit OnValueChanged(recipient, tokens[recipient]);
return true;
}
function getTokens(address recipient) view public returns (uint value) {
return tokens[recipient];
}
}
在migration文件中创建2_depoly_contracts.js写入
var SmartToken = artifacts.require("./SmartToken.sol");
module.exports = function(deployer) {
deployer.deploy(SmartToken);
};
四、编译部署合约
在SmartToken目录下执行,本地区块链要一直挖矿才能保持合约能上链
truffle compile
提示成功
sy@sy-PC:~/pi_node/Project/SmartToken$ truffle compile
Compiling your contracts...
===========================
> Compiling ./contracts/Migrations.sol
> Compiling ./contracts/SmartToken.sol
> Artifacts written to /home/sy/pi_node/Project/SmartToken/build/contracts
> Compiled successfully using:
- solc: 0.5.0+commit.1d4f565a.Emscripten.clang
truffle migration
提示成功
Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.
Starting migrations...
======================
> Network name: 'development'
> Network id: 18151213239
> Block gas limit: 0xe865d62e
1_initial_migration.js
======================
Deploying 'Migrations'
----------------------
> transaction hash: 0x0858fc6fdc563865867d08d64148a047678fafd85931af47ca9343b43b26e3e3
> Blocks: 0 Seconds: 188
> contract address: 0x345F8f043810fCDf8BcB17295b65E65478abc65F
> block number: 100
> block timestamp: 1578390352
> account: 0xfa0D3d82c76D1BE7689D2c893BAcB36814f879a9
> balance: 498
> gas used: 284908
> gas price: 20 gwei
> value sent: 0 ETH
> total cost: 0.00569816 ETH
> Saving migration to chain.
> Saving artifacts
-------------------------------------
> Total cost: 0.00569816 ETH
2_deploy_contracts.js
=====================
Deploying 'SmartToken'
----------------------
> transaction hash: 0x98a8dabc53fa74b17038251f3b11a68360e01c4c56f7abf2e64e00de96f24ad3
> Blocks: 1 Seconds: 8
> contract address: 0xd7FA3645Ae06061c900D2fa9ff9300826B29C3b5
> block number: 105
> block timestamp: 1578390365
> account: 0xfa0D3d82c76D1BE7689D2c893BAcB36814f879a9
> balance: 523
> gas used: 356625
> gas price: 20 gwei
> value sent: 0 ETH
> total cost: 0.0071325 ETH
> Saving migration to chain.
> Saving artifacts
-------------------------------------
> Total cost: 0.0071325 ETH
Summary
=======
> Total deployments: 2
> Final cost: 0.01283066 ETH
五、查看并调用合约
进入Truffle控制台
truffle console
查看SmartToken合约信息
SmartToken.deployed()
truffle(development)> SmartToken.deployed()
TruffleContract {
constructor:
{ [Function: TruffleContract]
_constructorMethods:
{ setProvider: [Function: setProvider],
new: [Function: new],
at: [Function: at],
deployed: [Function: deployed],
defaults: [Function: defaults],
hasNetwork: [Function: hasNetwork],
isDeployed: [Function: isDeployed],
detectNetwork: [Function: detectNetwork],
setNetwork: [Function: setNetwork],
setNetworkType: [Function: setNetworkType],
setWallet: [Function: setWallet],
resetAddress: [Function: resetAddress],
link: [Function: link],
clone: [Function: clone],
addProp: [Function: addProp],
toJSON: [Function: toJSON],
decodeLogs: [Function: decodeLogs] },
_properties:
{ contract_name: [Object],
contractName: [Object],
gasMultiplier: [Object],
timeoutBlocks: [Object],
autoGas: [Object],
numberFormat: [Object],
abi: [Object],
metadata: [Function: metadata],
network: [Function: network],
networks: [Function: networks],
address: [Object],
transactionHash: [Object],
links: [Function: links],
events: [Function: events],
binary: [Function: binary],
deployedBinary: [Function: deployedBinary],
unlinked_binary: [Object],
bytecode: [Object],
deployedBytecode: [Object],
sourceMap: [Object],
deployedSourceMap: [Object],
source: [Object],
sourcePath: [Object],
legacyAST: [Object],
ast: [Object],
compiler: [Object],
schema_version: [Function: schema_version],
schemaVersion: [Function: schemaVersion],
updated_at: [Function: updated_at],
updatedAt: [Function: updatedAt],
userdoc: [Function: userdoc],
devdoc: [Function: devdoc] },
_property_values: {},
_json:
{ contractName: 'SmartToken',
abi: [Array],
metadata:
'{"compiler":{"version":"0.5.0+commit.1d4f565a"},"language":"Solidity","output":{"abi":[{"constant":false,"inputs":[{"name":"recipient","type":"address"},{"name":"value","type":"uint256"}],"name":"depositToken","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"recipient","type":"address"}],"name":"getTokens","outputs":[{"name":"value","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"recipient","type":"address"},{"name":"value","type":"uint256"}],"name":"withdrawToken","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"OnValueChanged","type":"event"}],"devdoc":{"methods":{}},"userdoc":{"methods":{}}},"settings":{"compilationTarget":{"/home/sy/pi_node/Project/SmartToken/contracts/SmartToken.sol":"SmartToken"},"evmVersion":"byzantium","libraries":{},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"/home/sy/pi_node/Project/SmartToken/contracts/SmartToken.sol":{"keccak256":"0x863cf2f2ec2276f002b8ea441705308893130f30d807db16b9053db07b04faa8","urls":["bzzr://8d2ec07fda3f4c9e1876a8e890424faffb69a5009b740fad48af315a7c4f0546"]}},"version":1}',
bytecode:
'0x608060405234801561001057600080fd5b50610475806100206000396000f3fe608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063338b5dea1461005c578063450efe21146100cf5780639e281a9814610134575b600080fd5b34801561006857600080fd5b506100b56004803603604081101561007f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506101a7565b604051808215151515815260200191505060405180910390f35b3480156100db57600080fd5b5061011e600480360360208110156100f257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061028b565b6040518082815260200191505060405180910390f35b34801561014057600080fd5b5061018d6004803603604081101561015757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506102d3565b604051808215151515815260200191505060405180910390f35b6000816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff167f65dce515c55eb8d94c3ec733006907bb1a555ef5fb2ab7227019830d4f90a2596000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a26001905092915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600080826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540312156103665760008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506103b3565b816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b8273ffffffffffffffffffffffffffffffffffffffff167f65dce515c55eb8d94c3ec733006907bb1a555ef5fb2ab7227019830d4f90a2596000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a2600190509291505056fea165627a7a72305820bc162e7d429402117860b1226bfa0e06de754b0b45e587f04765de35164fcf370029',
deployedBytecode:
'0x608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063338b5dea1461005c578063450efe21146100cf5780639e281a9814610134575b600080fd5b34801561006857600080fd5b506100b56004803603604081101561007f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506101a7565b604051808215151515815260200191505060405180910390f35b3480156100db57600080fd5b5061011e600480360360208110156100f257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061028b565b6040518082815260200191505060405180910390f35b34801561014057600080fd5b5061018d6004803603604081101561015757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506102d3565b604051808215151515815260200191505060405180910390f35b6000816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff167f65dce515c55eb8d94c3ec733006907bb1a555ef5fb2ab7227019830d4f90a2596000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a26001905092915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600080826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540312156103665760008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506103b3565b816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b8273ffffffffffffffffffffffffffffffffffffffff167f65dce515c55eb8d94c3ec733006907bb1a555ef5fb2ab7227019830d4f90a2596000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a2600190509291505056fea165627a7a72305820bc162e7d429402117860b1226bfa0e06de754b0b45e587f04765de35164fcf370029',
sourceMap:
'26:812:1:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26:812:1;;;;;;;',
deployedSourceMap:
'26:812:1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;159:210;;8:9:-1;5:2;;;30:1;27;20:12;5:2;159:210:1;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;159:210:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;721:114;;8:9:-1;5:2;;;30:1;27;20:12;5:2;721:114:1;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;721:114:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;379:331;;8:9:-1;5:2;;;30:1;27;20:12;5:2;379:331:1;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;379:331:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;159:210;228:12;274:5;253:6;:17;260:9;253:17;;;;;;;;;;;;;;;;:26;;;;;;;;;;;310:9;295:44;;;321:6;:17;328:9;321:17;;;;;;;;;;;;;;;;295:44;;;;;;;;;;;;;;;;;;357:4;350:11;;159:210;;;;:::o;721:114::-;780:10;810:6;:17;817:9;810:17;;;;;;;;;;;;;;;;803:24;;721:114;;;:::o;379:331::-;449:12;511:1;502:5;482:6;:17;489:9;482:17;;;;;;;;;;;;;;;;:25;478:34;474:147;;;549:1;529:6;:17;536:9;529:17;;;;;;;;;;;;;;;:21;;;;474:147;;;604:5;583:6;:17;590:9;583:17;;;;;;;;;;;;;;;;:26;;;;;;;;;;;474:147;651:9;636:44;;;662:6;:17;669:9;662:17;;;;;;;;;;;;;;;;636:44;;;;;;;;;;;;;;;;;;698:4;691:11;;379:331;;;;:::o',
source:
'pragma solidity ^0.5.0; \n\ncontract SmartToken { \n mapping(address => uint) tokens; \n event OnValueChanged(address indexed _from, uint _value); \n \n function depositToken(address recipient, uint value) public returns (bool success) { \n tokens[recipient] += value; \n emit OnValueChanged(recipient, tokens[recipient]); \n return true; \n }\n \n function withdrawToken(address recipient, uint value) public returns (bool success) { \n if (int(tokens[recipient] - value) < 0) { \n tokens[recipient] = 0; \n } else { \n tokens[recipient] -= value; \n } \n emit OnValueChanged(recipient, tokens[recipient]); \n return true; \n } \n \n function getTokens(address recipient) view public returns (uint value) { \n return tokens[recipient]; \n } \n}\n',
sourcePath:
'/home/sy/pi_node/Project/SmartToken/contracts/SmartToken.sol',
ast: [Object],
legacyAST: [Object],
compiler: [Object],
networks: [Object],
schemaVersion: '3.0.9',
updatedAt: '2020-01-07T09:46:08.688Z',
devdoc: [Object],
userdoc: [Object] },
setProvider: [Function: bound setProvider],
new:
{ [Function: bound new] estimateGas: [Function: bound estimateDeployment] },
at: [Function: bound at],
deployed: [Function: bound deployed],
defaults: [Function: bound defaults],
hasNetwork: [Function: bound hasNetwork],
isDeployed: [Function: bound isDeployed],
detectNetwork: [Function: bound detectNetwork],
setNetwork: [Function: bound setNetwork],
setNetworkType: [Function: bound setNetworkType],
setWallet: [Function: bound setWallet],
resetAddress: [Function: bound resetAddress],
link: [Function: bound link],
clone: [Function: bound clone],
addProp: [Function: bound addProp],
toJSON: [Function: bound toJSON],
decodeLogs: [Function: bound decodeLogs],
web3:
Web3Shim {
currentProvider: [Getter/Setter],
_requestManager: [RequestManager],
givenProvider: null,
providers: [Object],
_provider: [HttpProvider],
setProvider: [Function],
BatchRequest: [Function: bound Batch],
extend: [Function],
version: '1.0.0-beta.37',
utils: [Object],
eth: [Eth],
shh: [Shh],
bzz: [Bzz],
networkType: undefined },
class_defaults:
{ from: '0xfa0D3d82c76D1BE7689D2c893BAcB36814f879a9',
gas: 6721975,
gasPrice: 20000000000 },
currentProvider:
HttpProvider {
host: 'http://127.0.0.1:8564',
httpAgent: [Agent],
timeout: 0,
headers: undefined,
connected: true,
send: [Function],
_alreadyWrapped: true },
network_id: '18151213239',
networkType: undefined },
methods:
{ 'depositToken(address,uint256)':
{ [Function]
call: [Function],
sendTransaction: [Function],
estimateGas: [Function],
request: [Function] },
'withdrawToken(address,uint256)':
{ [Function]
call: [Function],
sendTransaction: [Function],
estimateGas: [Function],
request: [Function] },
'getTokens(address)':
{ [Function]
call: [Function],
sendTransaction: [Function],
estimateGas: [Function],
request: [Function] } },
abi:
[ { anonymous: false,
inputs: [Array],
name: 'OnValueChanged',
type: 'event',
constant: undefined,
payable: undefined,
signature:
'0x65dce515c55eb8d94c3ec733006907bb1a555ef5fb2ab7227019830d4f90a259' },
{ constant: false,
inputs: [Array],
name: 'depositToken',
outputs: [Array],
payable: false,
stateMutability: 'nonpayable',
type: 'function',
signature: '0x338b5dea' },
{ constant: false,
inputs: [Array],
name: 'withdrawToken',
outputs: [Array],
payable: false,
stateMutability: 'nonpayable',
type: 'function',
signature: '0x9e281a98' },
{ constant: true,
inputs: [Array],
name: 'getTokens',
outputs: [Array],
payable: false,
stateMutability: 'view',
type: 'function',
signature: '0x450efe21' } ],
address: '0xd7FA3645Ae06061c900D2fa9ff9300826B29C3b5',
transactionHash: undefined,
contract:
Contract {
currentProvider: [Getter/Setter],
_requestManager:
RequestManager {
provider: [HttpProvider],
providers: [Object],
subscriptions: {} },
givenProvider: null,
providers:
{ WebsocketProvider: [Function: WebsocketProvider],
HttpProvider: [Function: HttpProvider],
IpcProvider: [Function: IpcProvider] },
_provider:
HttpProvider {
host: 'http://127.0.0.1:8564',
httpAgent: [Agent],
timeout: 0,
headers: undefined,
connected: true,
send: [Function],
_alreadyWrapped: true },
setProvider: [Function],
BatchRequest: [Function: bound Batch],
extend:
{ [Function: ex]
formatters: [Object],
utils: [Object],
Method: [Function: Method] },
clearSubscriptions: [Function],
options: { address: [Getter/Setter], jsonInterface: [Getter/Setter] },
defaultAccount: [Getter/Setter],
defaultBlock: [Getter/Setter],
methods:
{ depositToken: [Function: bound _createTxObject],
'0x338b5dea': [Function: bound _createTxObject],
'depositToken(address,uint256)': [Function: bound _createTxObject],
withdrawToken: [Function: bound _createTxObject],
'0x9e281a98': [Function: bound _createTxObject],
'withdrawToken(address,uint256)': [Function: bound _createTxObject],
getTokens: [Function: bound _createTxObject],
'0x450efe21': [Function: bound _createTxObject],
'getTokens(address)': [Function: bound _createTxObject] },
events:
{ OnValueChanged: [Function: bound ],
'0x65dce515c55eb8d94c3ec733006907bb1a555ef5fb2ab7227019830d4f90a259': [Function: bound ],
'OnValueChanged(address,uint256)': [Function: bound ],
allEvents: [Function: bound ] },
_address: '0xd7FA3645Ae06061c900D2fa9ff9300826B29C3b5',
_jsonInterface: [ [Object], [Object], [Object], [Object] ] },
OnValueChanged: [Function],
depositToken:
{ [Function]
call: [Function],
sendTransaction: [Function],
estimateGas: [Function],
request: [Function] },
withdrawToken:
{ [Function]
call: [Function],
sendTransaction: [Function],
estimateGas: [Function],
request: [Function] },
getTokens:
{ [Function]
call: [Function],
sendTransaction: [Function],
estimateGas: [Function],
request: [Function] },
sendTransaction: [Function],
send: [Function],
allEvents: [Function],
getPastEvents: [Function] }
调用合约
truffle(development)> var contract
undefined
truffle(development)> SmartToken.deployed().then(function(instance){contract=instance;});
undefined
truffle(development)> contract.depositToken("0xfa0d3d82c76d1be7689d2c893bacb36814f879a9",1)
{ tx:
'0xdf0401c8aed768aa710028b19eb61d04ef3899a6a757c462a3d2497c5a43605c',
receipt:
{ blockHash:
'0xc8c058b41698a930f88b4d8acc5d15ccfda3d342ed354c6d5facae3850995235',
blockNumber: 109,
contractAddress: null,
cumulativeGasUsed: 45266,
from: '0xfa0d3d82c76d1be7689d2c893bacb36814f879a9',
gasUsed: 45266,
logs: [ [Object] ],
logsBloom:
'0x00000000000000000000000200000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000100000000000000000200080000000000000000000000000000000000000020000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
root:
'0x6821000402b0f80f13c6d8bcc01b5b64a2f93b16ba33f75ed9e42f28d0ef067c',
to: '0xd7fa3645ae06061c900d2fa9ff9300826b29c3b5',
transactionHash:
'0xdf0401c8aed768aa710028b19eb61d04ef3899a6a757c462a3d2497c5a43605c',
transactionIndex: 0,
rawLogs: [ [Object] ] },
logs:
[ { address: '0xd7FA3645Ae06061c900D2fa9ff9300826B29C3b5',
blockNumber: 109,
transactionHash:
'0xdf0401c8aed768aa710028b19eb61d04ef3899a6a757c462a3d2497c5a43605c',
transactionIndex: 0,
blockHash:
'0xc8c058b41698a930f88b4d8acc5d15ccfda3d342ed354c6d5facae3850995235',
logIndex: 0,
removed: false,
id: 'log_1dcbd037',
event: 'OnValueChanged',
args: [Result] } ] }
truffle(development)> contract.getTokens("0xfa0d3d82c76d1be7689d2c893bacb36814f879a9")
<BN: 1>
可以看到,调用contract.depositToken 与 contract.getTokens
可以完成存款与查询余额的合约方法。
网友评论