以太坊 web3 转移代币 token

web3版本,1.0.0 beta,现阶段网上文档基本100%都是老版本,API差异很大,经过一番摸索猜测使用1.0.0搞定,provider使用的是https://rinkeby.infura.io。

web3文档写的很齐全,根据文档交易以太币没有问题(唯一需要注意的是必须先把account添加到wallet,这个文档中没写),转移代币就完全是另一回事了,转移代币的本质是操作合约的函数,因为几乎100%的JSON-RPC服务都不提供远程签名这类有风险的接口(自己搭建的服务貌似也不行,没有深入详细测试),所以必须要本地签名,文档上倒是有几个签名函数,但是绝对不会成功,目前不清楚文档中的几个签名函数是做什么用。

需要另外一个库实现,ethereumjs-tx,这是个nodejs的库,有对应的浏览器版本,详细看README.md,下面代码是浏览器版本实现。

//合约的interface
var abi = JSON.parse([...])
//第二个参数是合约的address
var token = new web3.eth.Contract(abi, '...');

//从地址from转移value个token到地址to。success和error是回调函数
var transfer = function(from, to, value, success, error) {
    try {
        //定义transaction
        var t = {
            to: ..., // 因为是调用合约,所以这个是合约地址
            value: '0x00', //转移的以太币数量为0
            data: token.methods.transfer(to, value).encodeABI() //要调用的合约函数,我用的ERC20标准
        }
    } catch(e) {
        if(undefined==error){
            error=console.log
        }
        // 很可能是to地址错误
        error(1)
        return
    }
    //获取当前gas价格
    web3.eth.getGasPrice().then(function(p) {
        t.gasPrice = web3.utils.toHex(p);
        //获取nonce
        web3.eth.getTransactionCount(from,
        function(err, r) {
            t.nonce = web3.utils.toHex(r);
            t.from = from;
            //暂时没用预估,代码先保留
            web3.eth.estimateGas(t,
            function(err, gas) {
                gas = '150000';
                t.gasLimit = web3.utils.toHex(gas);
                //初始化transaction
                var tx = new ethereumjs.Tx(t);
                var privateKey = ...
                if ('0x' == privateKey.substr(0, 2)) {
                    privateKey = privateKey.substr(2)
                }
                privateKey = new ethereumjs.Buffer.Buffer(privateKey, 'hex');
                //签名
                tx.sign(privateKey);
                var serializedTx = '0x' + tx.serialize().toString('hex');
                //发送原始transaction
                web3.eth.sendSignedTransaction(serializedTx,
                function(err, r) {
                    if(!err){
                        //根据hash获取完整的transaction,chrome开发者工具中,这里会一直有json-rpc,大概会有70多个,目前不清楚原因,知道的可以浏览解释下
                        web3.eth.getTransaction(r,
                        function(err, r) {
                            success(r)
                        })
                    }
                }).catch(function(err){
                    //gas不足
                    error(2)
                });
            })
        })
        return this
    })
}

转账成功之后去http://etherscan.io/去查一下即可。

 

发表评论

电子邮件地址不会被公开。

*