首页 文章

无法通过来自私有区块链中的非 Contract 运行节点的事务获得智能合约中的公共功能的值

提问于
浏览
2

任何人都可以帮忙解决这个问题......让我苦苦挣扎 .

上下文:包含所有Geth1.5.9 Go1.8.1的私有区块链

三个节点 . 两名矿工 .

节点1:Raspberry Pi与Raspbian(没有挖掘,它只是收集数据作为传感器)

节点2:使用Ubuntu14.04的 Cloud 主机

节点3:Mac OX 10.12

智能合约在节点2上运行,我将 eth.accounts[0] 设置为智能合约的创建者,这意味着 Instance.creator() 将是节点2上 eth.accounts[0] 的地址 .

码:

pragma solidity ^0.4.0;
contract PaperCopyright {
  struct Paper{
    string author;
    string fileHash;
    string title;
    uint date;
  }

  address public creator;

  Paper[] public papers;

  function PaperCopyright() {
    creator = msg.sender;
  }

  function add(string author,string file,string title) returns(bool) {
    if(msg.sender != creator) throw;
    papers.push(Paper({
        author: author,
        fileHash: file,
        title: title,
        date: now
    }));
    return true;
  }

  function edit(uint index,string author,string file,string title,uint  date) returns(bool) {
    if(msg.sender != creator) throw;
    papers[index] = Paper({
        author: author,
        fileHash: file,
        title: title,
        date: date
    });
    return true;
  }

  function (){
    throw;
  }
}

互动很好 .

检查 admin.peers ,它们都显示两个对等点 .

现在,

正常的以太交易都很好,没问题 . 我可以找到已成功转移的以太,并且可以在块中找到记录 .

如果在节点2上交付了一个事务,那么一切都很好,没问题 . 可以在块中找到事务记录,我可以调用 Instance.paper() 来获取存储在链上的返回值 .

If a transaction is delivered on Node 1 or Node 3 (Not the node running the smart contract), wrong things happen. 通过 eth.getTransactionReceipteth.getTransactioneth.getBlock 检查块信息,我们可以找到已成功放入链的参数,这意味着此特定事务应该已成功 . 当然,我通过 txpool.statuseth.getBlockTransactionCount("pending") 进行检查,每个节点上都会为零 . 但是,如果我尝试调用公共函数 Instance.papers() 以便返回值,则显示 " Error: new BigNumber() not a base 16 number:" ,这意味着 Contract 状态尚未更改 . 我不认为这是因为跨越这三个节点的非同步链问题,因为可以在块内找到transactionHash和transactionContent,并且 eth.blockNumber 完全相同 .

当然,我可以清楚地知道数据已经成功上传到链中存在块内的事务记录,但这对我来说非常奇怪,我希望直接调用public函数查找数据我放入我的私人连锁店 . 有任何想法吗?

1 回答

  • 0

    即使 Contract 抛出错误,也会记录交易

    假设您的交易进展顺利,因为链上记录的一个是错误的 .

    您说节点2是 Contract 的所有者,并且您的 Contract 仅在与节点2一起使用时才起作用 .

    这是因为 editadd 函数中的 if(msg.sender != creator) throw; .

    如果某人不是所有者执行该功能并回滚您的功能的任何副作用,这将停止执行该功能 . 但交易仍然写在Chain上 .

    因为我们希望保留事务的原子性,所以最安全的做法是还原所有更改并使整个事务(或至少调用)不起作用 .

    http://solidity.readthedocs.io/en/develop/control-structures.html#exceptions

相关问题