128

关于 Solidity 的 transaction 问题

jason_chen · 于 发布 · 最后由 chenyufeng回复 · 1215 次阅读

问题:

在调用solidity的写功能函数时,比如
function mint(address receiver, uint amount) {
if (msg.sender != minter) return;
balances[receiver] += amount;
}
如果该条件 if (msg.sender != minter) return;不满足,return返回的值是多少?我在写web3的js文件中
如何体现这种情况?

  • 947 large
    pan1907

    Hi,你是希望debug在(msg.sender != minter)的情况下会return什么值吗?

  • 128
    jason_chen

    你好!我当时是想问条件不满足后在web3.js读取到的是什么值,后来发现交易无法返回结果给web3.js,交易函数改变合约内数据,web3.js得到的交易结果是一个交易哈希,无法直接通过所得哈希值判断交易成功与否。不知道你有什么好的方法或者建议?

  • 128
    naituida

    像这些需要确认的交易实际是无法return任何值的, 只能得到交易的哈希,必须使用event

    event Mint(address indexed receiver, uint amount);
    function mint(address receiver, uint amount) {
            if (msg.sender != minter) return;
            balances[receiver] += amount;
            Mint(receiver, amount);
    }

    web3.js这边监听event

    event = contract.Mint();
    event.watch(...);

    对于constant的function,则可以得到返回值

    function query(address user) constant returns (uint) {
            return balances[user];
    }

    web3.js

    var balance = contract.query(addr);
  • 128
    jason_chen

    @naituida 也就是读的话能直接读出数据,而写需要一段时间的矿工确认后得到哈希值,但无法通过哈希值判断交易成功与否。
    我看了solidity文档说:event只能监听事件而不能监听结果,触发时可以在testrpc的输出中看到日志。
    如何根据event来判断交易成功与否啊?
    以注册用户为例,我在合约规定注册名不能重复,第1个人以用户名:a、密码:123注册可以写入,如果第二个人以相同的用户名注册则不能注册成功,我在web3.js的程序中无论成功与否,得到都只是一串哈希值,利用event如何通过监听得到返回值或者判断交易是否成功?

  • 128
    naituida

    你可以把结果放到event的参数里啊
    比如

    function register() {
       if(ok) {
            LogReg(msg.sender, true);
         } else {
            LogReg(msg.sender, false);
         }
    }
  • 128
    jason_chen

    @naituida 好的,谢谢!我试试

  • 128
    jason_chen

    @naituida 你好!我查了下文档,event在web3.js中应该监听事件而不是返回值,而且结果都是哈希值,不能判断啊

  • 128
  • 128
    jason_chen

    @naituida 谢谢!我看看这些资料。我看的文档:http://blog.csdn.net/fidelhl/article/details/50481859 我说的是交易也就是写功能,返回的是哈希值

  • 128
    naituida

    @jason_chen 你看的文档没有什么问题,这句话的意思其实就是针对你的需求。因为web3.js无法得到这个function的返回值,我们只有通过event记录你关心的返回值再监听
    你的文档中也有使用event的例子

  • 128
    jason_chen

    @naituida 如果返回值是哈希值的话,监听哈希值也没有办法在前端确定成功与否。 以注册用户为例,输入用户名和密码注册成功,第二次以相同的用户名注册,注册则不成功。无论注册成功与否,其交易的返回值都是哈希值,监听哈希值,前端如何判断注册是否成功?

  • 128
    naituida

    @jason_chen 这里说的是两件事情啊。。。
    1. web3.js 没法得到你的function的返回值,只能得到交易的hash
    2. 那么怎么办呢?你在function里创建event,这样在前端监听对应的event就能知道结果了

    contract

    event LogRegStatus(address user, bool result);
    function register() {
       if( isUsed(msg.sender)) {
           LogRegStatus(msg.sender, false);
         } else {
             createUser(msg.sender);
             LogRegStatus(msg.sender, true);
         }
    }

    web

    YourContract.LogRegStatus().watch(function(err, event) {
       if(event.args.result) {
                console.log("reg success");
         } else {
             console.log("reg failed");
         }
    });
  • 128
    jason_chen

    @naituida 好的,谢谢!

  • 128
    chenyufeng

    @naituida
    你好,根据你的方法,为什么我测试只能返回int/uint类型的数据,而不能返回bool、string类型。

  • 128
    chenyufeng

    经过测试,Event事件可以返回uint,int,address, bytes32, string, bool类型;
    但是不能返回任何的数组类型。

    合约中的实现:
    event LogRegStatus(address user, bool result);

    function register(int ui) {
    if(ui != 0) {
    LogRegStatus(msg.sender, true);
    }
    else {
    LogRegStatus(msg.sender, false);
    }
    }

    js中的实现:
    contractAddr.register(amount, {from: account}).then(function() {

    });

    contractAddr.LogRegStatus().watch(function(err, event) {

    if(event.args.result) {
    console.log("成功啦");
    }
    else {
    console.log("失败啦");
    }
    });