精华内容
下载资源
问答
  • 智能合约之间的调用
    千次阅读
    2020-05-14 10:49:55

     

    msg.sender在构造函数中:

    //构造函数
    constructor() public {
        owner = msg.sender;
    }
    
    function increse(address receiver, uint amount) public{
        require( owner == receiver);
        balances[receiver] += amount;
    }
    

    在构造函数中,msg.sender等于部署该合约的地址;

    更多相关内容
  • 以太坊智能合约之间调用

    千次阅读 2019-06-22 19:11:10
    已经有一个代币合约如C,需要实现一个合约,在这个合约调用代币合约C中的transfer函数,即转代币的函数。 要在一个合约调用另一个合约,可用用以下三种方式调用。 CALL:最常用调用,内置变量msg的值会被修改为...

    最近有个新的需求
    已经有一个代币合约如C,需要实现一个合约,在这个合约中调用代币合约C中的transfer函数,即转代币的函数。

    要在一个合约中调用另一个合约,可用用以下三种方式调用。

    • CALL:最常用调用,内置变量msg的值会被修改为调用者,执行环境为被调用者的运行环境。
    • DELEGATECALL:调用后内置变量msg的值不会修改为调用者,但执行环境为调用者的运行环境。
    • CALLCODE和DELEGATECALL: 是在调用者的上下文中执行, 可以修改调用者的storage; CALLCODE 阻止msg.sender和msg.value传递;
      而DELEGATECALL不阻止;

    在A的合约中,B.callcode(c的函数): c看到msg.sender是B;
    在A的合约中,B.delegatecall(c的函数): c看到msg.sender是A;

    可以看到,这三种方式都并不符合我们的需求。
    方法只有,先让用户调用代币合约C中的approve方法,再调用下面实现的合约中的depositToken方法。
    pragma solidity ^0.4.25;

    contract Deposit {
        
        bool public stopped = false;
        uint256 public totalDeposit=0;
        uint256 minDepositValue;
        address owner;
        address cTokenAddr=0x01c2ce7bd1bc34eed8a99d0ea0abee305362c143;
        uint256 minBlockGap;
        mapping(address => mapping(string=>uint256))  depositRecords;
        mapping(address=>mapping(string=>uint256))  withdrawRecords;
        uint256 public account=0;
        
        uint256 public blocknum ;
       
        constructor(uint256 _minValue,uint256 _minBlockGap) public {
            owner=msg.sender;
            minDepositValue=_minValue;
            minBlockGap=_minBlockGap;
        }
        
        event Withdraw(address indexed _from, string indexed _pk, uint indexed _value);
        event DepositToken(address indexed _from,address indexed _to,uint256 indexed _value);
    
    
        function depositToken(address _to,uint256 _value,string pk) public isRunning  validAddress returns (bool sucess) {
            require(_value>minDepositValue);
            bytes4 transferFromMethodId = bytes4(keccak256("transferFrom(address,address,uint256)"));
            if(cTokenAddr.call(transferFromMethodId,msg.sender,_to, _value)){
                 depositRecords[msg.sender][pk]+=_value;
                 totalDeposit+=_value;
                 emit DepositToken(msg.sender,_to,_value);
                 return true;
            }
            return false;
        }
        
        function setMinBlockGap(uint256 _blockGap) public onlyOwner {
            minBlockGap=_blockGap;
        }
    
        function withdraw(uint256 _value,string _pk) public onlyOwner isRunning  validAddress returns (bool sucess) {
            require(depositRecords[msg.sender][_pk]>_value);
            uint256 blockNumGap=getBlockNumGap(_pk);
            if(blockNumGap<minBlockGap)
                 return false;
                 
            bytes4 transferMethodId = bytes4(keccak256("transfer(address,uint256)"));
            if(cTokenAddr.call(transferMethodId,msg.sender, _value)){
                depositRecords[msg.sender][_pk]-=_value;
                withdrawRecords[msg.sender][_pk]=0;
                totalDeposit-=_value;
                emit Withdraw(msg.sender,_pk,_value);
                return true;
            }
            return false;
        }
    
      
        
        function getDeposit(string pk) public view returns (uint256){
            return depositRecords[msg.sender][pk];
        }
        
        function getDepositByAddr(address addr,string pk) public onlyOwner view returns(uint256){
            return depositRecords[addr][pk];
        }
        
        
        function RequestWithdraw(string pk) public returns (bool){
           getBlockNumGap(pk);
        }
        
        function getwithdrawRecords(string pk) public view returns (uint256){
            return withdrawRecords[msg.sender][pk];
        }
        
        function getBlockNum() private view returns (uint256){
            return block.number;
        }
        
      
        function getBlockNumGap(string pk) private returns (uint256){
            uint256 number=getBlockNum();
            if (withdrawRecords[msg.sender][pk]==0){
                withdrawRecords[msg.sender][pk]=number;
                return 0;
            }else{
                return number-withdrawRecords[msg.sender][pk];
            }
        }
        
        function getTotalDeposit()  public onlyOwner view returns (uint256){
            return totalDeposit;
        }
        
        function stop(address _to,bool ifTransfer) public onlyOwner returns (bool sucess) {
            stopped=true;
            if(!ifTransfer){
                return true;
            }
            bytes4 methodId = bytes4(keccak256("transfer(address,uint256)"));
            if(cTokenAddr.call(methodId,_to,totalDeposit)){
                totalDeposit=0;
                return true;
            }
           return false;
        }
        
        function () payable public {
            revert();
        }
        
        function start() public onlyOwner {
            stopped = false;
        }
      
        modifier onlyOwner {
            require(msg.sender == owner);
            _;
        }
        modifier isRunning {
            require(!stopped);
            _;
        }
        modifier validAddress {
            require(address(0) != msg.sender);
            _;
        }
    }
    
    
    展开全文
  • BSV 智能合约调用

    2022-03-18 19:30:01
    我们将介绍一种新颖的方法来调用另一个智能合约。方法建立在 OP_PUSH_TX 的技术之上。我们通过让一个合约调用另一个合约来求解二次方程来说明该方法。它已在 Sensible Contract 等项目中得到推广和广泛使用。 背景 ...

    我们将介绍一种新颖的方法来调用另一个智能合约。方法建立在 OP_PUSH_TX 的技术之上。我们通过让一个合约调用另一个合约来求解二次方程来说明该方法。它已在 Sensible Contract 等项目中得到推广和广泛使用。

    背景

    在这里插入图片描述

    sighash 原像格式规范

    从 sighash 原像的规范中,我们可以看到交易中的每个输入都有不同的 sighash 原像。我们还看到它们的原像有重叠的部分。最值得注意的是,它们共享相同的输出(彩色)。input0 和 input1 的原像都包括 output0 和 output1,如下面的示例交易1中突出显示的部分。我们利用这一特性来让两个合约相互通信。

    在这里插入图片描述

    在 2 个输入的 sighash 原像中都包含相同的输出

    合约间调用

    为了演示如何调用另一个合约,我们考虑求解一个二次方程的示例:a * x² + b * x + c = 0
    在这里插入图片描述

    下面列出了求解方程的合约。它将解 x 写入 output0。

    struct Coeff {
        int a;
        int b;
        int c;
    }
    
    contract Callee {
        static const int N = 2;
    
        public function solve(Coeff co, int x, SigHashPreimage txPreimage) {
            // Note: SigHash_SINGLE is used
            require(Tx.checkPreimageSigHashType(txPreimage, SigHash.SINGLE | SigHash.FORKID));
    
            // check x is a root
            require(co.a * x * x + co.b * x + co.c == 0);
    
            bytes data = num2bin(co.a, N) + num2bin(co.b, N) + num2bin(co.c, N) + num2bin(x, N);
            bytes outputScript = Utils.buildOpreturnScript(data);
            bytes output = Utils.buildOutput(outputScript, 0);
            require(hash256(output) == SigHash.hashOutputs(txPreimage));
        }
    }
    
    Callee 合约

    调用者Caller合约也可以访问 output0,可以提取解 x 并使用它,而无需求解 x 本身。也就是调用上面的Callee合约。

    
    contract Caller {
        static const int N = 2;
        static const int calleeContractInputIndex = 1;
        static const int selfContractInputIndex = 0;
        // hash of the callee contract, i.e., its locking script
        PubKeyHash calleeContractHash;
    
        public function call(Coeff co, bytes prevouts, bytes calleeContractTx,
            bytes outputScript, int amount, SigHashPreimage txPreimage) {
            require(Tx.checkPreimage(txPreimage));
            require(hash256(prevouts) == SigHash.hashPrevouts(txPreimage));
    
            // validate the tx containing the callee contract
            bytes prevScriptTxId = prevouts[calleeContractInputIndex * TxUtil.OUTPOINT_LEN : calleeContractInputIndex * TxUtil.OUTPOINT_LEN + TxUtil.TX_ID_LEN];
            require(hash256(calleeContractTx) == prevScriptTxId);
    
            // validate the callee contract, i.e., its locking script
            int lockContractTxOutIndex = Utils.fromLEUnsigned(prevouts[selfContractInputIndex * TxUtil.OUTPOINT_LEN + TxUtil.TX_ID_LEN : selfContractInputIndex * TxUtil.OUTPOINT_LEN + TxUtil.TX_ID_LEN + 4]);
            bytes prevScriptCode = TxUtil.readOutput(calleeContractTx, lockContractTxOutIndex).script;
            require(hash160(prevScriptCode) == this.calleeContractHash);
    
            int l = len(outputScript);
            int a = unpack(outputScript[l - 4 * N : l - 3 * N]);
            int b = unpack(outputScript[l - 3 * N : l - 2 * N]);
            int c = unpack(outputScript[l - 2 * N : l - N]);
            require(co == { a, b, c });
            int x = unpack(outputScript[l - N :]);
            // ------>> x must be a root for the following quadatic equition: no need to double check
            // require(a * x * x + b * x + c == 0);
    
            bytes output = Utils.buildOutput(outputScript, amount);
            require(hash256(output) == SigHash.hashOutputs(txPreimage));
        }
    }
    
    Caller 合约

    优点

    与通过将函数直接包含到合约本身来调用函数的直接方式相比,通过另一个单独的合约调用它有几个显着的优势。

    • 效率 : 一个有状态的合约可以有多个内部功能。每次它改变状态时,并不是所有的都必须被调用。然而,由于它们都是合约的一部分,它们都必须包含在内,从而导致交易规模膨胀。通过将它们放入单独的合约中,只从主合约调用给定调用所需的那些,从而节省大量成本,尤其是在有许多功能时。
    • 可扩展性 : 一个通用函数可以包装到一个库合约中,可以从任何其他合约调用,而无需了解其内部实现细节。这使它与调用合约2 解耦。

    致谢

    该技术由 Sensible Contract 的 Chen Cheng、Jiejiang 和 Lu Gu 以及 Cambridge Cryptographic 的 Ying Chan 独立发明。


    [1] 假设使用了 SIGHASH_ALL。

    [2] 库合约的作者可以通过要求在合约被调用时必须向他控制的地址支付小额款项来获得收益。

    展开全文
  • 智能合约内部调用另一个智能合约

    千次阅读 2018-10-16 19:11:18
    最近在看以太坊,顺便记录一下,这篇文章的目的是一个智能合约调用另一个智能合约的方法,写个demo记录一下 pragma solidity ^0.4.18; contract DataContract { mapping (address =&gt; uint256) public ...

    最近在看以太坊,顺便记录一下,这篇文章的目的是一个智能合约调用另一个智能合约的方法,写个demo记录一下

    pragma solidity ^0.4.18;
    
    contract DataContract {
        mapping (address => uint256) public balanceOf;
    
        function setBlance(address _address, uint256 v) public  {
            balanceOf[_address] = v;
        }
    
    }
    
    contract ControlContract {
        mapping (address => uint256) public tmp;
        DataContract dataContract;
    
        function ControlContract(address _dataContractAddr) public {
            dataContract = DataContract(_dataContractAddr);
        }
    
        function set(uint256 value) public {
            dataContract.setBlance(msg.sender, value);
            tmp[msg.sender] = value + 10;
        }
    }
    

     

    说明 DataContract合约提供了一个公共方法setBalance, ControlContract合约中会调用set方法来更新自己与DataContract保存的数据。

    首先部署DataContract合约,然后部署ControlContract合约,在创建的时候需要指定DataContract合约地址。

    首先调用set方法

    发送成功后就可以查看了

    至此一个合约调用另一个合约可以实现

    展开全文
  • 1. 接口A // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface A { function a()external view returns(uint256);...2.智能合约B // SPDX-License-Identifier: MIT pragma solidity ^0.8
  • solidity 智能合约之间调用

    千次阅读 2019-07-30 15:43:34
    智能合约之间调用 在区块链上,有些功能往往无法通过一个智能合约完成,此时便会用到智能合约之间调用。本篇文章带大家通过具体示例来了解一下智能合约之间调用。 在智能合约的编译过程中,有两种情况:调用者...
  • 摘要合约之间调用权限出现问题,”Note: The called function should be payable if you send value and the value you send should be less than your current balance.” Note: The called function ...
  • 合约之间通过调用或发送消息的方式进行交互 。当一个合约接收到一条消息时,它可以回复一些数据,这样消息的原发送者就能立即使用 。采用这种方法,发送一条消息就像调用一次函数。 一个智能合约能够给其他智能...
  • 本文介绍三种类型的合约调用; 注意:本文合约均编译通过,仅供参考;
  • 一、以太币传输方式 在三种以太币传输方式中,以太币的接收方都由位于开头的<address> 指定。 1、transfer ...address payable>.transfer(uint256 amount) ...//发生异常情况时,只会返.
  • web3.js调用ETH智能合约里的函数

    千次阅读 2021-03-03 20:35:18
        以太坊的智能合约里的公有变量,可以被web3.js通过call()方式来读取出来,也可以被web3.js通过contractObj.methods.XXXfun(numParam).encodeABI()来更新该变量。     下面,介绍使用web3.js读取和修改Bob...
  • 本文介绍“接口直接调用法”,实现合约合约调用; 这种方式调用,是最简单方便的调用方式,缺点是只能调用固定的接口,不够灵活。 以下是调用一个已经部署的合约的 deposit 方法。 pragma solidity ^0.5.10;...
  • EOS中合约之间是可以相互调用的,主要通过inline action完成合约之间调用。 譬如在掷骰子游戏中,存在两个玩家先下注资金,然后比较骰子大小后决定胜负,赢的那一方将获得所有的下注资金。在eosio源代码eos/build/...
  • 使用geth在以太坊私链中部署合约并调用智能合约的函数 在上一个教程中我们已经创建了一个私链了,接下来我们将在这个私链上创建用户并挖矿,再使用此用户来部署智能合约,并调用其中的函数 环境:linux操作系统 ...
  • 在控制台里面呢通过输入命令的方式,可以来调取一些智能合约的方法 IPC的方式也成为管道通信 主要是进程之间的一个调用方式 HTTP的方式 这个是比较常见的一些方式 通常是使用JSON格式来做数据的序列化与反序列化 ...
  • eth 以太坊合约之间相互调用

    千次阅读 2018-10-30 09:01:29
    准备: remix ...demo1.sol pragma solidity ^0.4.25;... * 有所有人的合约 * 所有权限管理都在这里定义 * event OwnershipTransferred(address, address) * modifier onlyOwner() */ contract ...
  • 上篇介绍“接口直接调用法”,实现合约合约调用;只能调用固定的接口,不够灵活。 本文介绍“通用型调用法”,实现合约合约调用; 通用型调用一般直接使用 call 方法调用。这种方式调用较灵活,缺点是容易...
  • 首先我们了解合约的创建!直接贴代码,通过代码给大家分析。 pragma solidity ^0.4.24; contract C1 { uint256 public value ; constructor(uint256 input) public { value = input; } function ...
  • 智能合约展示了供应链如何改善卖方和买方之间的真实性,效率和隐私。 智能合约可模拟Parmigiano Reggiano供应链。 目录结构 以太坊_SupplyChian 图表 Parmigiano_Reggiano_Activity_Diagram.png Parmigiano_...
  • 区块链 --- 智能合约

    千次阅读 2022-02-14 15:36:02
    智能合约是一种旨在以信息化方式传播、验证或执行合同的计算机协议,主要起到了数据执行的作用。可以减少对信任中间人的需求,降低仲裁和执行成本。
  • Axelar的通用消息传递(General Message Passing,GMP)允许智能合约能够进行跨链通信。
  • 本文介绍了涉及到动态数组时Solidity与Vyper智能合约相互调用的方法,给那些极稀有的使用该方式的场景提供参考。
  • 最近开始学习以太坊智能合约编程,其中涉及到智能合约之间的函数调用。 Solidity的三种合约间的调用方式有call、delegatecall 和 callcode这3种方式。参考了下面的文章: ...对于文章中提到的三种调用方式的异同点 ...
  • 一个超级简到的示例合约如下: pragma solidity >0.4.24; contract Demo{ string name; uint age; //定义事件 event Instructor(string name, uint age); function set(string memory _name, uint _age) ...
  • web3.js中有一些与交易发送、签名、合约函数调用相关的api,初学者(如me)常常搞不清什么情况下应该调用哪个,以及它们之间的区别。现将个人浅见记录如下,备忘。 交易发送 sendTransaction web3.eth....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,940
精华内容 2,376
热门标签
关键字:

智能合约之间的调用