一.环境安装
1.1 nodejs安装
- 1.下载nodejs二进制包
wget https://nodejs.org/download/release/v10.12.0/node-v10.12.0-linux-x64.tar.xz
- 2.解压压缩包
tar xvf node-v10.12.0-linux-x64.tar.xz
- 更改包名
mv node-v10.12.0-linux-x64 /usr/local/nodejs
- 添加环境变量
# vim /etc/profile #nodejs export NODE_HOME=/usr/local/nodejs export PATH=$NODE_HOME/bin:$PATH
- 生效环境变量
source /etc/profile
- 查看nodejs版本号
# node -v v10.12.0
- 查看npm版本号
```npm -v
6.4.1
## 1.2 solc安装 - 安装solc版本为erc20_usdt合约指定版本
npm -g install solc@0.4.17
- 查看solc版本
solcjs --version
0.4.17+commit.bdeb9e52.Emscripten.clang
# 二.下载ERC20_USDT合约 ## 2.1 erc20_sudt合约查看链接 https://cn.etherscan.com/address/0xdac17f958d2ee523a2206206994597c13d831ec7#contracts ## 2.2 erc20_sudt合约文件存放 将链接中erc20_sudt合约复制下来放到以下文件中
vim /opt/data/contract/usdt.sol
/**
*Submitted for verification at Etherscan.io on 2017-11-28
*/
pragma solidity ^0.4.17;
/**
@title SafeMath
@dev Math operations with safety checks that throw on error
/
library SafeMath {
function mul(uint256 a, uint256 b) internal pure returns (uint256) {if (a == 0) { return 0; } uint256 c = a * b; assert(c / a == b); return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0 uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a); return a - b;
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b; assert(c >= a); return c;
}
}
/**
@title Ownable
@dev The Ownable contract has an owner address, and provides basic authorization control
functions, this simplifies the implementation of "user permissions".
/
contract Ownable {
address public owner;/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */
function Ownable() public {
owner = msg.sender;
}
/**
* @dev Throws if called by any account other than the owner. */
modifier onlyOwner() {
require(msg.sender == owner); _;
}
/**
- @dev Allows the current owner to transfer control of the contract to a newOwner.
- @param newOwner The address to transfer ownership to.
- /
function transferOwnership(address newOwner) public onlyOwner {
if (newOwner != address(0)) {owner = newOwner;
}
}
}
/**
- @title ERC20Basic
- @dev Simpler version of ERC20 interface
- @dev see https://github.com/ethereum/EIPs/issues/20
- /
contract ERC20Basic {
uint public _totalSupply;
function totalSupply() public constant returns (uint);
function balanceOf(address who) public constant returns (uint);
function transfer(address to, uint value) public;
event Transfer(address indexed from, address indexed to, uint value);
}
/**
- @title ERC20 interface
- @dev see https://github.com/ethereum/EIPs/issues/20
- /
contract ERC20 is ERC20Basic {
function allowance(address owner, address spender) public constant returns (uint);
function transferFrom(address from, address to, uint value) public;
function approve(address spender, uint value) public;
event Approval(address indexed owner, address indexed spender, uint value);
}
/**
@title Basic token
@dev Basic version of StandardToken, with no allowances.
/
contract BasicToken is Ownable, ERC20Basic {
using SafeMath for uint;mapping(address => uint) public balances;
// additional variables for use if transaction fees ever became necessary
uint public basisPointsRate = 0;
uint public maximumFee = 0;/**
@dev Fix for the ERC20 short address attack.
/
modifier onlyPayloadSize(uint size) {
require(!(msg.data.length < size + 4));
_;
}/**
@dev transfer token for a specified address
@param _to The address to transfer to.
@param _value The amount to be transferred.
/
function transfer(address _to, uint _value) public onlyPayloadSize(2 * 32) {
uint fee = (_value.mul(basisPointsRate)).div(10000);
if (fee > maximumFee) {fee = maximumFee;
}
uint sendAmount = _value.sub(fee);
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(sendAmount);
if (fee > 0) {balances[owner] = balances[owner].add(fee); Transfer(msg.sender, owner, fee);
}
Transfer(msg.sender, _to, sendAmount);
}/**
@dev Gets the balance of the specified address.
@param _owner The address to query the the balance of.
@return An uint representing the amount owned by the passed address.
/
function balanceOf(address _owner) public constant returns (uint balance) {
return balances[_owner];
}
}
/**
@title Standard ERC20 token
@dev Implementation of the basic standard token.
@dev Based oncode by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
/
contract StandardToken is BasicToken, ERC20 {mapping (address => mapping (address => uint)) public allowed;
uint public constant MAX_UINT = 2**256 - 1;
/**
@dev Transfer tokens from one address to another
@param _from address The address which you want to send tokens from
@param _to address The address which you want to transfer to
@param _value uint the amount of tokens to be transferred
/
function transferFrom(address _from, address _to, uint _value) public onlyPayloadSize(3 * 32) {
var _allowance = allowed[_from][msg.sender];// Check is not needed because sub(_allowance, _value) will already throw if this condition is not met
// if (_value > _allowance) throw;uint fee = (_value.mul(basisPointsRate)).div(10000);
if (fee > maximumFee) {fee = maximumFee;
}
if (_allowance < MAX_UINT) {allowed[_from][msg.sender] = _allowance.sub(_value);
}
uint sendAmount = _value.sub(fee);
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(sendAmount);
if (fee > 0) {balances[owner] = balances[owner].add(fee); Transfer(_from, owner, fee);
}
Transfer(_from, _to, sendAmount);
}/**
@dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
@param _spender The address which will spend the funds.
@param _value The amount of tokens to be spent.
/
function approve(address _spender, uint _value) public onlyPayloadSize(2 * 32) {// To change the approve amount you first have to reduce the addresses
// allowance to zero by calling
approve(_spender, 0)` if it is not
// already 0 to mitigate the race condition described here:
// https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
require(!((_value != 0) && (allowed[msg.sender][_spender] != 0)));allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
}/**
@dev Function to check the amount of tokens than an owner allowed to a spender.
@param _owner address The address which owns the funds.
@param _spender address The address which will spend the funds.
@return A uint specifying the amount of tokens still available for the spender.
/
function allowance(address _owner, address _spender) public constant returns (uint remaining) {
return allowed[_owner][_spender];
}
}
/**
@title Pausable
@dev Base contract which allows children to implement an emergency stop mechanism.
/
contract Pausable is Ownable {
event Pause();
event Unpause();bool public paused = false;
/**
@dev Modifier to make a function callable only when the contract is not paused.
/
modifier whenNotPaused() {
require(!paused);
_;
}/**
@dev Modifier to make a function callable only when the contract is paused.
/
modifier whenPaused() {
require(paused);
_;
}/**
@dev called by the owner to pause, triggers stopped state
/
function pause() onlyOwner whenNotPaused public {
paused = true;
Pause();
}/**
@dev called by the owner to unpause, returns to normal state
/
function unpause() onlyOwner whenPaused public {
paused = false;
Unpause();
}
}
contract BlackList is Ownable, BasicToken {
/////// Getters to allow the same blacklist to be used also by other contracts (including upgraded Tether) /////// function getBlackListStatus(address _maker) external constant returns (bool) { return isBlackListed[_maker]; } function getOwner() external constant returns (address) { return owner; } mapping (address => bool) public isBlackListed; function addBlackList (address _evilUser) public onlyOwner { isBlackListed[_evilUser] = true; AddedBlackList(_evilUser); } function removeBlackList (address _clearedUser) public onlyOwner { isBlackListed[_clearedUser] = false; RemovedBlackList(_clearedUser); } function destroyBlackFunds (address _blackListedUser) public onlyOwner { require(isBlackListed[_blackListedUser]); uint dirtyFunds = balanceOf(_blackListedUser); balances[_blackListedUser] = 0; _totalSupply -= dirtyFunds; DestroyedBlackFunds(_blackListedUser, dirtyFunds); } event DestroyedBlackFunds(address _blackListedUser, uint _balance); event AddedBlackList(address _user); event RemovedBlackList(address _user);
}
contract UpgradedStandardToken is StandardToken{
// those methods are called by the legacy contract
// and they must ensure msg.sender to be the contract address
function transferByLegacy(address from, address to, uint value) public;
function transferFromByLegacy(address sender, address from, address spender, uint value) public;
function approveByLegacy(address from, address spender, uint value) public;
}
contract TetherToken is Pausable, StandardToken, BlackList {
string public name; string public symbol; uint public decimals; address public upgradedAddress; bool public deprecated; // The contract can be initialized with a number of tokens // All the tokens are deposited to the owner address // // @param _balance Initial supply of the contract // @param _name Token Name // @param _symbol Token symbol // @param _decimals Token decimals function TetherToken(uint _initialSupply, string _name, string _symbol, uint _decimals) public { _totalSupply = _initialSupply; name = _name; symbol = _symbol; decimals = _decimals; balances[owner] = _initialSupply; deprecated = false; } // Forward ERC20 methods to upgraded contract if this one is deprecated function transfer(address _to, uint _value) public whenNotPaused { require(!isBlackListed[msg.sender]); if (deprecated) { return UpgradedStandardToken(upgradedAddress).transferByLegacy(msg.sender, _to, _value); } else { return super.transfer(_to, _value); } } // Forward ERC20 methods to upgraded contract if this one is deprecated function transferFrom(address _from, address _to, uint _value) public whenNotPaused { require(!isBlackListed[_from]); if (deprecated) { return UpgradedStandardToken(upgradedAddress).transferFromByLegacy(msg.sender, _from, _to, _value); } else { return super.transferFrom(_from, _to, _value); } } // Forward ERC20 methods to upgraded contract if this one is deprecated function balanceOf(address who) public constant returns (uint) { if (deprecated) { return UpgradedStandardToken(upgradedAddress).balanceOf(who); } else { return super.balanceOf(who); } } // Forward ERC20 methods to upgraded contract if this one is deprecated function approve(address _spender, uint _value) public onlyPayloadSize(2 * 32) { if (deprecated) { return UpgradedStandardToken(upgradedAddress).approveByLegacy(msg.sender, _spender, _value); } else { return super.approve(_spender, _value); } } // Forward ERC20 methods to upgraded contract if this one is deprecated function allowance(address _owner, address _spender) public constant returns (uint remaining) { if (deprecated) { return StandardToken(upgradedAddress).allowance(_owner, _spender); } else { return super.allowance(_owner, _spender); } } // deprecate current contract in favour of a new one function deprecate(address _upgradedAddress) public onlyOwner { deprecated = true; upgradedAddress = _upgradedAddress; Deprecate(_upgradedAddress); } // deprecate current contract if favour of a new one function totalSupply() public constant returns (uint) { if (deprecated) { return StandardToken(upgradedAddress).totalSupply(); } else { return _totalSupply; } } // Issue a new amount of tokens // these tokens are deposited into the owner address // // @param _amount Number of tokens to be issued function issue(uint amount) public onlyOwner { require(_totalSupply + amount > _totalSupply); require(balances[owner] + amount > balances[owner]); balances[owner] += amount; _totalSupply += amount; Issue(amount); } // Redeem tokens. // These tokens are withdrawn from the owner address // if the balance must be enough to cover the redeem // or the call will fail. // @param _amount Number of tokens to be issued function redeem(uint amount) public onlyOwner { require(_totalSupply >= amount); require(balances[owner] >= amount); _totalSupply -= amount; balances[owner] -= amount; Redeem(amount); } function setParams(uint newBasisPoints, uint newMaxFee) public onlyOwner { // Ensure transparency by hardcoding limit beyond which fees can never be added require(newBasisPoints < 20); require(newMaxFee < 50); basisPointsRate = newBasisPoints; maximumFee = newMaxFee.mul(10**decimals); Params(basisPointsRate, maximumFee); } // Called when new token are issued event Issue(uint amount); // Called when tokens are redeemed event Redeem(uint amount); // Called when contract is deprecated event Deprecate(address newAddress); // Called if contract ever adds fees event Params(uint feeBasisPoints, uint maxFee);
}
# 三.编辑js文件 ## 3.1 编写合约js文件
vim /opt/data/deploy_usdt.js
let Web3 = require("web3")
let solc = require("solc")
let fs = require("fs")
// 监听同步节点
web3 = new Web3(new Web3.providers.HttpProvider("http://192.168.21.207:8545"));
// 导入合约文件
let source = fs.readFileSync("./contract/usdt.sol", "utf8");
// 编译合约
let cacl = solc.compile(source, 1);
console.log("=============================")
console.log("version: " + web3.version);
console.log("=============================")
console.log(solc.version())
console.log("=============================")
console.log(cacl.contracts)
let abi = JSON.parse(cacl.contracts[':TetherToken'].interface);
console.log("=============================")
console.log(abi)
console.log("=============================")
let bytecode = cacl.contracts[':TetherToken'].bytecode;
console.log(bytecode)
console.log("=============================")
let sender = "0x6e60f5243e1a3f0be3f407b5afe9e5395ee82aa2";
// 部署合约
new web3.eth.Contract(abi).deploy({
data: "0x" + bytecode,
arguments: [2718282552619854,"Tether USD","USDT",6],
}).send({
from: sender,
gas: 3070000,
gasPrice: 130000000000
}, function (error) {
if (error != null) {
console.log("部署失败: " + error);
}
}).then(function (newContractInstance) {
// 获取合约地址 var newContractAddress = newContractInstance.options.address console.log("部署成功,合约地址:\n" + newContractAddress.toLowerCase());
});
## 3.2 修改合约js文件相应参数 - 1、监听以太坊节点地址 > 注:以太坊私链可连接地址
web3 = new Web3(new Web3.providers.HttpProvider("http://192.168.21.207:8545"));
- 2、导入的合约文件路径 > 注:智能合约文件目录为:./contract/erc20.sol
let source = fs.readFileSync("./contract/usdt.sol", "utf8");
- 3、需要部署的合约名称 > 注:TetherToken为修改的合约名称
let abi = JSON.parse(cacl.contracts[':TetherToken'].interface);
console.log("=============================")
console.log(abi)
console.log("=============================")
let bytecode = cacl.contracts[':TetherToken'].bytecode;
console.log(bytecode)
console.log("=============================")
- 4、部署合约的地址 > 注:该地址需要提前准备,并充值足够的ETH用于部署智能合约
let sender = "0x6e60f5243e1a3f0be3f407b5afe9e5395ee82aa2";
- 5、部署合约参数
arguments: [2718282552619854,"Tether USD","USDT",6],
> 参数解释
参数1:发行总量: 2718282552619854 (注意:此处erc20_usdt因小数位精度为6,所以需要有6位小数,)
参数2:币名全称:Tether USD
参数3:币名:USDT
参数4:小数位精度:6 (注意:此处含义是小数位精度为多少)
- 6、修改gas费
gas: 3070000, gasPrice: 130000000000
> 注:以上表示在以太坊中部署该合约愿意花费 200 gwei * 3070000 的手续费,即0.3991 ETH,而==部署合约的地址中ETH余额必须大于此值== # 四.解锁以太坊账户
docker exec -it eth-v1.10.5 bash
bash-5.0# geth attach
解锁以太坊账户
personal.unlockAccount('0x6e60f5243e1a3f0be3f407b5afe9e5395ee82aa2','111222333',300)
true
# 五.部署合约 命令:node deploy_usdt.js
node deploy_usdt.js
=============================
version: 1.4.0
=============================
0.4.17+commit.bdeb9e52.Emscripten.clang
=============================
......
=============================
部署成功,合约地址:
0x0f794c5803c04b18ecf5dd90ea8831212580321e
> 注:以太坊私链测试环境erc20_usdt智能合约地址:0x0f794c5803c04b18ecf5dd90ea8831212580321e # 六.以太坊私链代币接口使用 ## 6.1 获取ETH指定代币的余额 ### 6.1.1 请求参数详情及解释 - 请求参数详情
{
"jsonrpc": "2.0",
"method": "eth_call",
"params": [
{
"from": "0x6e60f5243e1a3f0be3f407b5afe9e5395ee82aa2",
"to": "0x0f794c5803c04b18ecf5dd90ea8831212580321e",
"data": "0x70a082310000000000000000000000006e60f5243e1a3f0be3f407b5afe9e5395ee82aa2"
},"latest"
],
"id": 1
}
- 请求参数解释
method:eth_call :获取代币的余额
from:钱包地址,即转账方
to:代币地址,即智能合约地址
data数据格式:最前边的“0x70a08231000000000000000000000000”是固定的,后边“6e60f5243e1a3f0be3f407b5afe9e5395ee82aa2”的是钱包地址(不带“0x”前缀)
### 6.1.2 请求响应详情及解释 - 请求响应详情
{
"jsonrpc": "2.0",
"id": 1,
"result": "0x0000000000000000000000000000000000000000000000000009a84379f2b34e"
}
- 请求响应解释
result字段的值,就是余额
### 6.1.3 命令行请求实例
curl -H Content-Type:application/json -X POST --data '{"jsonrpc":"2.0","method":"eth_call","params":[{"from":"0x6e60f5243e1a3f0be3f407b5afe9e5395ee82aa2","to":"0x0f794c5803c04b18ecf5dd90ea8831212580321e","data":"0x70a082310000000000000000000000006e60f5243e1a3f0be3f407b5afe9e5395ee82aa2"},"latest"],"id":1}' http://127.0.0.1:8545
请求响应:
{"jsonrpc":"2.0","id":1,"result":"0x0000000000000000000000000000000000000000000000000009a84379f2b34e"}
## 6.2 ETH代币转账 ### 6.2.1 请求参数详情及解释 - 请求参数详情
{
"jsonrpc": "2.0",
"method": "eth_sendTransaction",
"params": [
{
"from": "0x6e60f5243e1a3f0be3f407b5afe9e5395ee82aa2",
"to": "0x0f794c5803c04b18ecf5dd90ea8831212580321e",
"gas": "0x186a0",
"gasPrice": "0x0",
"value": "0x0",
"data": "0xa9059cbb000000000000000000000000dac76091b14c8f638245a1a501f8ef797437515e0000000000000000000000000000000000000000000000000000000005f5e100"
}
],
"id": 1
}
- 请求参数解释
method:eth_sendTransaction :代币转账
from:钱包地址,即转账方
to:代币地址,即智能合约地址
gas:交易执行可用gas量
gasPrice:gas价格
data数据格式:
共分为三段含义:
最前边的“0xa9059cbb000000000000000000000000”是固定的,含义为转账调用的方法;
中间“dac76091b14c8f638245a1a501f8ef797437515e”是钱包地址,即接收方方(不带“0x”前缀)
最后“0000000000000000000000000000000000000000000000000000000005f5e100”是转账金额,为十六进制
### 6.2.2 请求响应详情及解释 - 请求响应详情
{
"jsonrpc": "2.0",
"id": 1,
"result": "0x3adb3046c4fb8e2798608256d5399a9d72f7e16eac1c6d33a7ecb1e2e96d57f1"
}
- 请求响应解释
result字段的值,就是交易哈希
### 6.2.3 命令行请求实例
curl -H Content-Type:application/json -X POST --data '{"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{"from":"0x6e60f5243e1a3f0be3f407b5afe9e5395ee82aa2","to":"0x0f794c5803c04b18ecf5dd90ea8831212580321e","gas":"0x186a0","gasPrice":"0x0","value":"0x0","data":"0xa9059cbb000000000000000000000000dac76091b14c8f638245a1a501f8ef797437515e0000000000000000000000000000000000000000000000000000000005f5e100"}],"id":1}' http://127.0.0.1:8545
请求响应:
{"jsonrpc":"2.0","id":1,"result":"0x3adb3046c4fb8e2798608256d5399a9d72f7e16eac1c6d33a7ecb1e2e96d57f1"}
## 6.3 ETH交易哈希查询 ### 6.3.1 请求参数详情及解释 - 请求参数详情
{
"jsonrpc": "2.0",
"method": "eth_getTransactionByHash",
"params": [
"0x3adb3046c4fb8e2798608256d5399a9d72f7e16eac1c6d33a7ecb1e2e96d57f1"
],
"id": 1
}
- 请求参数解释
method:eth_getTransactionByHash :根据交易哈希查询交易信息
0x3adb3046c4fb8e2798608256d5399a9d72f7e16eac1c6d33a7ecb1e2e96d57f1:需要查询的交易哈希
### 6.3.2 请求响应详情及解释 - 请求响应详情
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"blockHash": "0x34167f9d85316401e944f41ec976b8aea5d23c1f1d66f87a01954eb1cdfb4dd4",
"blockNumber": "0x800",
"from": "0x6e60f5243e1a3f0be3f407b5afe9e5395ee82aa2",
"gas": "0x186a0",
"gasPrice": "0x0",
"hash": "0x3adb3046c4fb8e2798608256d5399a9d72f7e16eac1c6d33a7ecb1e2e96d57f1",
"input": "0xa9059cbb000000000000000000000000dac76091b14c8f638245a1a501f8ef797437515e0000000000000000000000000000000000000000000000000000000005f5e100",
"nonce": "0x1",
"to": "0x0f794c5803c04b18ecf5dd90ea8831212580321e",
"transactionIndex": "0x0",
"value": "0x0",
"type": "0x0",
"v": "0x145878",
"r": "0x865deb166afb2c6b8fe8f2e7b43d26914d3c895a4cf94cef9f917e8fb179be66",
"s": "0x1744da9f64d0b09860a24848227038f6a5214e453593f4a5a036196c092e3dcc"
}
}
- - 请求响应解释
blockHash:区块哈希
blockNumber:区块编号
from:交易发起账号
gas:gas用量
gasPrice:gas价格
hash:交易哈希
input:交易额外数据
nonce:nonce值
to:智能合约地址
transactionIndex:交易序号
value:交易金额
### 6.3.3 命令行请求实例
curl -H Content-Type:application/json -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionByHash","params":["0x3adb3046c4fb8e2798608256d5399a9d72f7e16eac1c6d33a7ecb1e2e96d57f1"],"id":1}' http://127.0.0.1:8545
请求响应:
{"jsonrpc":"2.0","id":1,"result":{"blockHash":"0x34167f9d85316401e944f41ec976b8aea5d23c1f1d66f87a01954eb1cdfb4dd4","blockNumber":"0x800","from":"0x6e60f5243e1a3f0be3f407b5afe9e5395ee82aa2","gas":"0x186a0","gasPrice":"0x0","hash":"0x3adb3046c4fb8e2798608256d5399a9d72f7e16eac1c6d33a7ecb1e2e96d57f1","input":"0xa9059cbb000000000000000000000000dac76091b14c8f638245a1a501f8ef797437515e0000000000000000000000000000000000000000000000000000000005f5e100","nonce":"0x1","to":"0x0f794c5803c04b18ecf5dd90ea8831212580321e","transactionIndex":"0x0","value":"0x0","type":"0x0","v":"0x145878","r":"0x865deb166afb2c6b8fe8f2e7b43d26914d3c895a4cf94cef9f917e8fb179be66","s":"0x1744da9f64d0b09860a24848227038f6a5214e453593f4a5a036196c092e3dcc"}}
## 6.4 ETH检查智能合约交易 查看智能合约交易是否详情,是否成功 ### 6.4.1 请求参数详情及解释 - 请求参数详情
{
"jsonrpc": "2.0",
"method": "eth_getTransactionReceipt",
"params": [
"0x3adb3046c4fb8e2798608256d5399a9d72f7e16eac1c6d33a7ecb1e2e96d57f1"
],
"id": 1
}
- 请求参数解释
method:eth_getTransactionReceipt :根据交易哈希查询交易信息
0x3adb3046c4fb8e2798608256d5399a9d72f7e16eac1c6d33a7ecb1e2e96d57f1:需要查询的交易哈希
### 6.4.2 请求响应详情及解释
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"blockHash": "0x34167f9d85316401e944f41ec976b8aea5d23c1f1d66f87a01954eb1cdfb4dd4",
"blockNumber": "0x800",
"contractAddress": null,
"cumulativeGasUsed": "0xdc82",
"effectiveGasPrice": "0x0",
"from": "0x6e60f5243e1a3f0be3f407b5afe9e5395ee82aa2",
"gasUsed": "0xdc82",
"logs": [{
"address": "0x0f794c5803c04b18ecf5dd90ea8831212580321e",
"topics": ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", "0x0000000000000000000000006e60f5243e1a3f0be3f407b5afe9e5395ee82aa2", "0x000000000000000000000000dac76091b14c8f638245a1a501f8ef797437515e"],
"data": "0x0000000000000000000000000000000000000000000000000000000005f5e100",
"blockNumber": "0x800",
"transactionHash": "0x3adb3046c4fb8e2798608256d5399a9d72f7e16eac1c6d33a7ecb1e2e96d57f1",
"transactionIndex": "0x0",
"blockHash": "0x34167f9d85316401e944f41ec976b8aea5d23c1f1d66f87a01954eb1cdfb4dd4",
"logIndex": "0x0",
"removed": false
}],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000200000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000004000000000000008000000000000000008000000010000000000001000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000004000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000",
"status": "0x1",
"to": "0x0f794c5803c04b18ecf5dd90ea8831212580321e",
"transactionHash": "0x3adb3046c4fb8e2798608256d5399a9d72f7e16eac1c6d33a7ecb1e2e96d57f1",
"transactionIndex": "0x0",
"type": "0x0"
}
}
### 6.4.3 命令行请求实例
curl -H Content-Type:application/json -X POST --data '{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0x3adb3046c4fb8e2798608256d5399a9d72f7e16eac1c6d33a7ecb1e2e96d57f1"],"id":1}' http://127.0.0.1:8545
{"jsonrpc":"2.0","id":1,"result":{"blockHash":"0x34167f9d85316401e944f41ec976b8aea5d23c1f1d66f87a01954eb1cdfb4dd4","blockNumber":"0x800","contractAddress":null,"cumulativeGasUsed":"0xdc82","effectiveGasPrice":"0x0","from":"0x6e60f5243e1a3f0be3f407b5afe9e5395ee82aa2","gasUsed":"0xdc82","logs":[{"address":"0x0f794c5803c04b18ecf5dd90ea8831212580321e","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000006e60f5243e1a3f0be3f407b5afe9e5395ee82aa2","0x000000000000000000000000dac76091b14c8f638245a1a501f8ef797437515e"],"data":"0x0000000000000000000000000000000000000000000000000000000005f5e100","blockNumber":"0x800","transactionHash":"0x3adb3046c4fb8e2798608256d5399a9d72f7e16eac1c6d33a7ecb1e2e96d57f1","transactionIndex":"0x0","blockHash":"0x34167f9d85316401e944f41ec976b8aea5d23c1f1d66f87a01954eb1cdfb4dd4","logIndex":"0x0","removed":false}],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000200000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000004000000000000008000000000000000008000000010000000000001000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000004000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000","status":"0x1","to":"0x0f794c5803c04b18ecf5dd90ea8831212580321e","transactionHash":"0x3adb3046c4fb8e2798608256d5399a9d72f7e16eac1c6d33a7ecb1e2e96d57f1","transactionIndex":"0x0","type":"0x0"}}
# 七.报错解决 ## 7.1 Error: Cannot find module 'web3' - 使用npm部署合约时报错:Error: Cannot find module 'web3' - 报错解决执行命令: npm install web3 ## 7.2 Error: Cannot find module 'solc' - 使用npm部署合约时报错:Error: Cannot find module 'solc' - 报错解决执行命令: npm install solc ## 7.3 AssertionError [ERR_ASSERTION]: Invalid callback object specified. - 使用npm部署合约时报错:AssertionError [ERR_ASSERTION]: Invalid callback object specified. - 报错解决执行命令:
切换solc版本为合约指定版本