Solidity

契約適用於 testrpc,但不適用於 Rinkeby。使用委託呼叫(可升級契約)模式並嘗試將 new Contract() 添加到數組失敗

  • November 25, 2017

我有一系列在 testrpc 上執行良好的合約,但在我部署到 Rinkeby 時卻不行。我正在使用 Zeppelin 的標準代幣合約,我對此沒有任何問題。

問題在於註冊契約。我有一份BaseRegistry來自https://regis.nu/的契約。我可以在這裡展示它,但我認為重要的是我的子契約繼承自BaseContract. 這是ChildRegistry

pragma solidity ^0.4.11;

import "./BaseRegistry.sol";
import "../token/Token.sol";
import "../node/Node.sol";


contract ChildRegistry is BaseRegistry {

address public owner;
address public nodeDelegateAddress;
address[] public registeredNodes;

address public delegateContract;
address[] public previousDelegates;
uint256 public count;
address public tokenAddress;

 event DelegateChanged(address oldAddress, address newAddress);

 function ChildRegistry() {
   // constructor
 }

 function changeDelegate(address _newDelegate) returns (bool) {
   /*assert(owner == msg.sender);*/

   if (_newDelegate != delegateContract) {
       previousDelegates.push(delegateContract);
       var oldDelegate = delegateContract;
       delegateContract = _newDelegate;
       DelegateChanged(oldDelegate, _newDelegate);
       return true;
     }
   return false;

}

 function registerNode() {
   delegateContract.delegatecall(bytes4(sha3("registerNode()")));
 }

 function createNodeContract () {
   delegateContract.delegatecall(bytes4(sha3("createNodeContract()")));
 }

 function getNodes() constant returns (address[]) {
   return registeredNodes;
 }

 function setTokenAddress(address _tokenAddress) {
   delegateContract.delegatecall(bytes4(sha3("setTokenAddress(address)")), _tokenAddress);
 }
 function setNodeDelegateAddress(address _nodeDelegateAddress) {
   delegateContract.delegatecall(bytes4(sha3("setNodeDelegateAddress(address)")), _nodeDelegateAddress);
 }


}

正在呼叫委託合約並在ChildRegistry設置後更新其自己的狀態:

pragma solidity ^0.4.11;

import "./BaseRegistry.sol";
import "../token/Token.sol";
import "../node/Node.sol";


contract ChildRegistryDelegate is BaseRegistry {

address public owner;
address public nodeDelegateAddress;
address[] public registeredNodes;

address public delegateContract;
address[] public previousDelegates;
uint256 public count;
address public tokenAddress;

 function ChildRegistryDelegate() {
   // constructor
 }


 function registerNode() {

   count += 1;

   Token existingToken = Token(tokenAddress);
   token.burn(1,msg.sender);
   register(msg.sender, "string");      
 //tokenAddress.call(bytes4(sha3("burn(uint256,address)")),1,msg.sender);

   createNodeContract();
 }

 function createNodeContract () {

   Node newNode = new Node();
   newNode.changeDelegate(nodeDelegateAddress);
   newNode.setOwner(msg.sender);
   newNode.setTokenAddress(tokenAddress);
   registeredNodes.push(newNode);

   /*newNode.call(bytes4(sha3("changeDelegate(address)")), nodeDelegateAddress);
   newNode.call(bytes4(sha3("setOwner(address)")), msg.sender);
   newNode.call(bytes4(sha3("changeDelegate(address)")), tokenAddress);*/

   registeredNodes.push(newNode);
 }

 function getNodes() constant returns (address[]) {
   return registeredNodes;
 }

 function setTokenAddress(address _tokenAddress) {
   tokenAddress = _tokenAddress;
 }

 function setNodeDelegateAddress(address _nodeDelegateAddress) {
   assert(owner == msg.sender);
   nodeDelegateAddress = _nodeDelegateAddress;
 }

}

當我部署契約時,我手動設置了適當的代表。我知道這些delegatecall作品,因為我可以setTokenAddress而且setNodeDelegateAddress非常好。問題是當我registerNode. 在 testrpc 上,它工作正常。當我部署到 Rinkeby 時,沒有任何效果。沒有任何內容被添加到registeredNodesregister不會被呼叫,並且token.burn不起作用。

我添加了count以查看delegatecall然後會起作用,並且確實如此。當我將所有內容註釋掉並添加tokenAddress.call(bytes4(sha3("burn(uint256,address)")),1,msg.sender);.

當我打電話時createNodeContract,也沒有任何效果。當我評論所有函式呼叫並嘗試Node newNode = new Node();registeredNodes.push(newNode);沒有任何反應時。

我不確定為什麼會這樣。我覺得這與BaseRegistry契約及其繼承方式有關。我也認為這可能是我使用松露部署契約的方式。這是我的2_deploy_contracts.js

var Token = artifacts.require('./Token.sol')
var ChildRegistry = artifacts.require('./ChildRegistry.sol')
var ChildRegistryDelegate = artifacts.require('./ChildRegistryDelegate.sol')
var NodeDelegate = artifacts.require('./NodeDelegate.sol')

module.exports = function(deployer) {
 deployer.deploy(Token);
 deployer.deploy(ChildRegistry);
 deployer.deploy(ChildRegistryDelegate);
 deployer.deploy(NodeDelegate);
};

我還認為這可能與我如何部署它們有關。我不知道。任何事情都會有所幫助。謝謝你。

弄清楚了。truffle.jsGeth 控制台由於某種原因沒有讀取我的文件。看起來像這樣:

rinkeby: {
 host: "localhost",
 port: 8545,
 network_id: "4",
 from: "0xfc7846d06fab273c62cda0d29eac0936a22eeca4",
 gas: 2000000
}

還是沒讀。一切正常,但交易耗盡了燃料並且失敗了。必須在每筆交易中手動添加氣體{from:sender, gas:2000000}才能使其正常工作。

引用自:https://ethereum.stackexchange.com/questions/31439