blockchain - Solidity - 如何从外部合约调用智能合约实例?

标签 blockchain ethereum solidity embark

我创建了一个 AccountManager 智能合约和它的两个实例(PARTYA 和 PARTYB)。
调用 TransferAgent.transfer(AccountManager.address, AccountManager.address) 时,我可以看到 accounts[msg.sender].balance 按预期更新。
但是,当调用实例(PARTYA 和 PARTYB)时,例如 TransferAgent.transfer(PARTYA.address, PARTYB.address) 余额中没有反射(reflect)任何变化。

我花了一些时间研究如何使用地址从 TransferAgent(外部契约(Contract))调用 AccountManager(实例),但找不到任何特定于此的内容。我无法获得平衡以反射(reflect)变化。有什么建议?

环境
- 以太坊
- 启动框架
- 坚固性

我的设置如下

合约.json

    {
      "default": {
        "gas": "auto",
        "contracts": {
          "SimpleStorage": {
            "args": [
              100
            ]
          },
          "Agent" : {
            "args": [
            ]
          },
          "AccountManager" : {
            "args": [
            ]
          },
          "PARTYA" : {
            "instanceOf" : "AccountManager",
            "args" : [
            ]       
          },
          "PARTYB" : {
            "instanceOf" : "AccountManager",
            "args" : [
            ]       
          },
          "TransferAgent" : {
            "args": [
            ]
          }
        }
      }
    }

Agent.sol
pragma solidity ^0.4.0;

contract Agent {
/* Define variable owner of the type address*/
address owner;

/* this function is executed at initialization and sets the owner of the contract */
function Agent() { owner = msg.sender; }

/* Function to recover the funds on the contract */
function kill() { if (msg.sender == owner) selfdestruct(owner); }
}

contract AccountManager is Agent {
enum ACTIVE { Y, N } 
enum STATUS { CREDIT, DEBIT }
mapping (address => Account) public accounts;

struct Account {
    bytes32 ssn;
    int balance;
    ACTIVE active;
    STATUS status;
}

modifier withdrawValidation(int withdrawAmt) {
    if( withdrawAmt <= accounts[msg.sender].balance)  {
        throw;
    }
    _;
}

// Check for current account matching 
modifier transferValidation(address _from, address _to, bytes32 _ssn) {
    if( AccountManager(_from).getSSN() != _ssn || 
            AccountManager(_to).getSSN() != _ssn || 
                AccountManager(_from).getStatus() == STATUS.CREDIT )  {
        throw;
    }
    _;
}

function register(bytes32 _ssn) public returns (bool success) {
    Account memory newRegistree;
    newRegistree.ssn = _ssn;
    newRegistree.balance = 0;
    newRegistree.active = ACTIVE.Y;
    newRegistree.status = STATUS.DEBIT;
    accounts[msg.sender] = newRegistree;
    return true;
}

function update(bytes32 _ssn) public returns (bool success) {
    accounts[msg.sender].ssn = _ssn;
    return true;
}

function deposit(int _depositAmt) public returns(bool success) {
    accounts[msg.sender].balance += _depositAmt;
    return true;
}

function withdraw(int _withdrawAmt) public returns(bool success) {
    accounts[msg.sender].balance = (accounts[msg.sender].balance - _withdrawAmt);
    return true;
}

function getBalance() public constant returns(int balance) {
    return accounts[msg.sender].balance;
}

function setBalance(int _balance) external returns(bool success) {
    accounts[msg.sender].balance = _balance;
    return true;
}

function setStatus() internal {
    if(accounts[msg.sender].balance >= 0)
        accounts[msg.sender].status = STATUS.DEBIT;
    else 
        accounts[msg.sender].status = STATUS.CREDIT;
}

function getStatus() external constant returns (STATUS status) {
    return accounts[msg.sender].status;
}

function getSSN() external constant returns(bytes32 ssn) {
    return accounts[msg.sender].ssn;
}

function getAccount() public constant returns (bytes32 ssn, int balance, ACTIVE active, STATUS status) {
    return (accounts[msg.sender].ssn, accounts[msg.sender].balance, accounts[msg.sender].active, accounts[msg.sender].status);
}
}

contract TransferAgent is Agent {
function transfer(address _from, address _to) public returns (bool success) {
    AccountManager(_from).setBalance(100); // not working for instances PARTYA,PARTYB
    AccountManager(_to).setBalance(200); // not working for instances PARTYA,PARTYB    }
}

最佳答案

这是一个非常简约的示例,它只专注于将交易发送到另一个合约。

“Hub”将部署两个“Spoke”,然后您可以使用 function local()向其中一个辐条发送消息。双方都记录了事件,因此您可以看到正在发生的事情。

contract Hub {

  Spoke public A;
  Spoke public B;

  event LogTXNSent(address spoke);

  function Hub() {
    A = new Spoke();
    B = new Spoke();
  }

  function local(address spokeAddress)
    public
    returns(bool success)
  {
    if(spokeAddress != address(A) && spokeAddress != address(B)) throw;
    if(!Spoke(spokeAddress).logEvent()) throw;
    LogTXNSent(spokeAddress);
    return true;
  }

}

contract Spoke {

  event LogTXNFrom(address sender);

  function logEvent()
    public
    returns(bool success)
  {
    LogTXNFrom(msg.sender);
    return true;
  }
}

希望能帮助到你。

关于blockchain - Solidity - 如何从外部合约调用智能合约实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43029639/

相关文章:

blockchain - 在 Solidity/Ethereum 中寻找高分的算法

hyperledger-fabric - Hyperledger Fabric 和 Hyperledger Indy 之间的跨账本通信

ethereum - web3.js 和 web3-light.js 有什么区别?

cryptography - 发送和传输仅适用于应付地址类型的对象,不适用于地址类型的对象。

ruby - 无法将非字符串解码为 common.Address 类型的 Go 结构字段 SendTxArgs.from

node.js - super 账本结构 : Invalid network configuration due to missing configuration data

ethereum - 限制 geth API RPC 方法的部分内容

bytecode - 以太坊字节码 JUMP 和 JUMPDEST 是如何解决的?

node.js - Web3.js 查看方法 call() 错误,因为返回值无效,是否耗尽了气体

boolean - Solidity:为什么错误的输入将我的 boolean 值设置为 "true"?