首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可靠智能契约继承函数输出失败

可靠智能契约继承函数输出失败
EN

Ethereum用户
提问于 2018-06-05 16:16:53
回答 1查看 752关注 0票数 0

我正在尝试将父契约中的一个函数继承到子契约中,并在混合JavaScript VM中很好地工作。我做了以下步骤:

  1. 在混合JavaScript VM中部署父契约。
  2. 通过执行父契约中的storeValue函数存储一些随机值
  3. 复制父契约的地址并在子契约中实例化它--如果我从子契约调用getValue函数--基本上是从父契约调用获取存储值函数--输出是一个值数组,一切都很正常。

如果我在私有区块链上部署这两个契约,我将得到一个空的值数组。我采取了以下步骤:

  1. 启动私有区块链(geth客户端)
  2. 在混合中将环境更改为Web3提供程序
  3. 在私有链中部署混合的WEB3DEPLOY代码,并从私有链复制挖掘地址的地址
  4. 使用该地址在子合同中实例化父合同。
  5. 重复部署儿童合同的过程
  6. 使用python笔记本中的web3.py输入值

现在,如果我在前端直接调用父契约中的函数accountTx,它可以正常工作。但是,如果我从前端的子合同调用继承的函数getValue,则结果是一个空数组。

因此,问题是,当部署在私有链上时,我无法获得函数getValue的输出,该函数是从另一个契约调用函数的。但是它在混合JavaScript VM中工作得很好。

父母合同:

代码语言:javascript
复制
pragma solidity ^0.4.20;

contract Parent {

    uint256[] values;
    mapping (address => uint256[])transactions;


    function storeValue(uint256 _value) {

        transactions[msg.sender].push(_value);
    }

    function accountTx(address addr) constant returns(uint256[]) {

        return (transactions[addr]);
    }

}

儿童合同:

代码语言:javascript
复制
pragma solidity ^0.4.20;

import './Parent.sol';


contract Child {

  /* instantiating parent contract*/
  Parent p = Parent(0x9dd1e8169e76a9226b07ab9f85cc20a5e1ed44dd);


   function getValue() public view returns (uint256[]){
      return p.accountTx(msg.sender);
  }

}

我已经将父契约的实例创建为全局实例,因为我确实希望将它用于某些函数。

是不是缺少了一些东西,比如将函数声明为external?如有任何指导,我们将不胜感激,谢谢。

EN

回答 1

Ethereum用户

发布于 2018-06-11 17:32:18

我怀疑你可能误解了“合同”的继承。

有两种不同的想法看起来很相似。让我们考虑它们:

  1. 有一个合同A和一个合同B,他们需要沟通。A不是B,B不是A,但是A需要足够的关于B的信息,才能与它进行通信,反过来。
  2. 有一段可重用的代码可以处理低级别的关注点。将它导入到许多契约中是很方便的,这样他们就可以“继承”逻辑。

这是两个完全不同的问题。

您可能会生成一段可重用的代码(故意不完整以保持原点):

Stoppable.sol

代码语言:javascript
复制
contract Stoppable {

    bool public isRunning;

    modifier onlyIfRunning {
        require(isRunning);
        _;
    }

    function Stoppable() public {
        isRunning = true;
    }

    function setRunSwitch(bool newSetting) public returns(bool contractRunning) {
        isRunning = newSetting;
    }
}

太棒了。现在,如果我们希望A或B是可停止的,我们只需转到contract A is Stoppable {...,并将onlyIfRunning修饰符添加到我们想要保护的状态变化函数中。A将获得状态变量isRunning以及函数setRunSwtich(),因为每当部署A时,它都会继承代码并运行构造函数。

现在,考虑另一种情况。B想要检查一些关于A的东西,或者B想要向A发送一个事务。这与继承无关。这是关于B有足够的信息可以与实例A对话。

B需要

  1. A使用的函数签名
  2. A实例的地址(它部署在哪里?)

A.sol

代码语言:javascript
复制
contract A {

  bytes32 public something;

  function setSomething(bytes32 newThing) public {
    something = newThing;
  }
}

B.sol

代码语言:javascript
复制
contract B {

  A a; // Type A (source available in the contract above), called "a"

  function B(address aAddress) public { // inform B where it can find an instance of A
    a = A(aAddress);
  }

  function getSomethingFromA() public view returns(bytes32 theThing) {
    return a.something();
  }
}

这在一开始不会编译,因为没有定义A。在B.sol中你会

代码语言:javascript
复制
import "./A.sol"; 

这样编译器就可以看到它并计算出B需要的接口信息。请注意,我们没有说任何类似B is A的内容。

如果前面的内容过于抽象,请考虑一个由音乐会门票、乐队、场地和活动组成的系统,每一个都代表在一组连锁合同中。让契约继承一组公共的权限和管理契约可能是明智的,就像停止的想法一样。像事件这样的联锁合同可能会检查乐队和场地,以确认事情是有意义的,所以他们需要一点界面和行踪方面的知识。

说活动是场地还是场地是乐队似乎是不明智的。当它开始像那样扭曲,这是滥用继承的迹象。

希望能帮上忙。

票数 1
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/50507

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档