精华内容
下载资源
问答
  • solidity 智能合约之间的调用

    千次阅读 2019-07-30 15:43:34
    智能合约之间的调用 在区块链上,有些功能往往无法通过一个智能合约完成,此时便会用到智能合约之间的调用。本篇文章带大家通过具体示例来了解一下智能合约之间的调用。 在智能合约的编译过程中,有两种情况:调用者...

    智能合约之间的调用

    在区块链上,有些功能往往无法通过一个智能合约完成,此时便会用到智能合约之间的调用。本篇文章带大家通过具体示例来了解一下智能合约之间的调用。

    在智能合约的编译过程中,有两种情况:调用者和被调用者在一个sol文件中和分别在不同的文件中。

    同sol文件的智能合约调用

    在下面的智能合约中,Demo1和Demo在同一个文件中,可进行同时编译,然后逐个发布。

    pragma solidity ^0.5.10;
    
    contract Demo1{
        
        uint public data;
        
        function setData(uint _data) public {
            data = _data;
        }
    }
    
    contract Demo2{
        function toSetData(Demo1 demo1,uint _data) public {
            demo1.setData(_data);
        }
    }
    

    当发布完成,可通过第Demo2的toSetData方法进行Demo1方法的调用。传递的第一个参数为Demo1的智能合约地址,第二个参数为要设置的值。

    不同sol文件的智能合约调用

    在大多数情况下,两个智能合约不存在于同一个sol文件中,那么就需要使用另外一种形式来进行调用。还拿调用Demo1方法来举例,用另外一个sol文件中的Demo3来调用Demo1。

    首先需要声明接口,然后在Demo3中直接调用对应的接口。

    pragma solidity ^0.5.10;
    
    contract Demo1{
        function setData(uint _data) public;
    }
    
    contract Demo3{
        function toSetData(Demo1 demo1,uint _data) public {
            demo1.setData(_data);
        }
    }
    

    调用接口是传递的参数依旧同第一种情况。

    原文链接:https://www.choupangxia.com/2019/07/30/solidity-智能合约之间的调用/


    程序新视界

    关注程序员的职场生涯,大量优质学习资源、技术文章分享

    csdn-微信公众号

    展开全文
  • 以太坊智能合约之间的调用

    千次阅读 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);
            _;
        }
    }
    
    
    展开全文
  • msg.sender在构造函数中: //构造函数 constructor() public { owner = msg.sender; } function increse(address receiver, uint amount) public{ ...在构造函数中,msg.sender等于部署该合约的地址; ...

     

    msg.sender在构造函数中:

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

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

    展开全文
  • 合约调用方式 合约调用的三种方式 ...主要是进程之间的一个调用方式 HTTP的方式 这个是比较常见的一些方式 通常是使用JSON格式来做数据的序列化与反序列化 也就是HTTP的JSON RPC的方式 websocke...

    合约调用方式

    • 合约调用的三种方式
      • IPC方式
        • 通常是通过控制台的方式
        • 以太网的节点在运行之后,可以打开一个控制台
        • 在控制台里面呢通过输入命令的方式,可以来调取一些智能合约的方法
        • IPC的方式也成为管道通信
        • 主要是进程之间的一个调用方式
      • HTTP的方式
        • 这个是比较常见的一些方式
        • 通常是使用JSON格式来做数据的序列化与反序列化
        • 也就是HTTP的JSON RPC的方式
      • websocket的方式
        • 以太坊内部支持使用websocket协议直接对节点内部一些合约接口来进行调用
    • 在这三种方式中,我们通过客户端来调的话是后两种,HTTP的JSON RPC的方式以及websocket方式
    • 而第一种IPC的方式更多的是在本机本节点来做一些访问调试,是进程之间的一种管道通信方式

    RPC/IPC调用

    • 上面是Go语言版本的以太坊全节点程序
    • 也是以太坊官方维护的一个优先级最高的一个节点程序的版本叫geth,也就是Go语言的eth节点
    • 它运行之后,可以通过这个命令 $ geth console,带上这么一个子命令,这样来运行全节点以后,就会进入到一个控制台,就能进入到控制台
    • 在控制台里面它会打印出一些与连接相关的信息,我们可以在这里看到它有 IPC endpoint,也就是IPC的一个连接地址
    • 这里是使用MAC系统来运行的,它是在这个/Users/mac/Library/Ethereum/geth.ipc默认的位置生成一个这样一个文件geth.ipc
    • 这个IPC的连接通信方式就是通过这个共享的一个文件来进行连接的
    • 也可以来打开另外一个控制台,只要来指向这个ipc文件就可以
    • 另外就是HTTP的链接地址, 我们是在本地,所以它是127.0.0.1, 端口号是8545
    • 进入控制台以后可以通过很多的命令来访问以太的节点
    • 控制台中输入exit命令可以退出

    常用RPC调用框架

    • 对于以太节点来讲,它是支持一个节点内部的RPC服务端
    • 对于客户端来讲的,目前已经支持了很多种语言的版本,比如支持Javascript的语言版本叫web3.js,这个版本也是最常用的版本
    • 除此以外,有面向Java语言的web3j
    • 面向C#的Nethereum
    • 支持Ruby语言的ethereum-ruby
    • 以及随着发展可能也会去支持其他语言的版本
    • 当然也可以自己来封装,这可能是因为以太RPC的支持的接口都是开源的,我们也可以自己来根据需要来来做自己的封装
    Library Language Project Page
    web3.js JavaScript https://github.com/ethereum/web3.js
    web3j Java https://github.com/web3j/web3j
    Nethereum C# .NET https://github.com/Nethereum/Nethereum
    ethereum-ruby Ruby https://github.com/DigixGlobal/ethereum-ruby

    关于web3对象

    • web3.js对象
      • 以太坊JavaScript API
        • 在web3这个github仓库中可以看到, https://github.com/ethereum/web3.js/tree/1.x/packages 这个目录
        • 是包含了一组已经封装好的客户端的调用库, 它是以太坊的Js版本的SDK
        • 导入后,有个类叫Web3, 在web3这个库里调用了上面的各个子库,来实现了这么一个封装,可查看官网示例
      • 普通 JSON RPC
        • 参数和返回值都是通过json来序列化和反序列化的
      • 需要配合以太坊节点使用
        • 可以是正式主网节点,也可是测试部署私有或模拟节点
    • web3对象的调用测试代码
      var Web3 = require('web3');
      if(typeof web3 !== 'undefined') {
          web3 = new Web3(web3.currentProvider);
      } else {
          // set the provider you want from Web3.providers
          web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
      }
      var Version = web3.version;
      console.log("client version: " + version);
      

    基于Nodejs示例

    var Web3 = require('web3');
    if(typeof web3 !== 'undefined') {
        web3 = new Web3(web3.currentProvider);
    } else {
        // set the provider you want from Web3.providers
        web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
    }
    
    web3.eth.getAccounts(console.log);
    

    输出10个生成的地址

    null [
      '0x437615686191efF890C7cCa136cfbf21Cb6451E6',
      '0xe4a56746DAfDf247BF125d5809B2D6168722Eb37',
      '0x23604b6563d63D5f3b4C9a09ADe681F5f2811DB6',
      '0x4900AEeA7CC7F76E473805c50E8F0e49c1F99D8E',
      '0x1A32509bC3DAA2AC5493AE212064e59ebeaED34c',
      '0x7c0c971814dBA35D5c53E5650b71E91ecb8C31fa',
      '0x2DB7594e84DC79EE782f3962C1ea9cC2912c3EF1',
      '0x9D86096d38B4460Be319dA56265499D863ccB5c4',
      '0xD03cbC188201EB3AB61aC465Dc1e3A2fa517245C',
      '0x77238F0407aF96Fd26Fe22A9996B2349F1ebb91f'
    ]
    
    展开全文
  • EOS中合约之间是可以相互调用的,主要通过inline action完成合约之间的调用。 譬如在掷骰子游戏中,存在两个玩家先下注资金,然后比较骰子大小后决定胜负,赢的那一方将获得所有的下注资金。在eosio源代码eos/build/...
  • 合约之间通过调用或发送消息方式进行交互 。当一个合约接收到一条消息时,它可以回复一些数据,这样消息原发送者就能立即使用 。采用这种方法,发送一条消息就像调用一次函数。 一个智能合约能够给其他智能...
  • 在geth客户端调用已部署的智能合约

    千次阅读 2018-01-31 14:51:56
    什么是合约? 合约是代码(它功能)和数据(它状态)集合,存在于以太坊区块链特定地址。 合约账户能够在彼此之间传递信息,进行图灵完备...也有其他语言可以用于编写智能合约如Serpent和LLL,在下一节会
  • 最近开始学习以太坊智能合约编程,其中涉及到智能合约之间的函数调用。 Solidity的三种合约间的调用方式有call、delegatecall 和 callcode这3种方式。参考了下面的文章: ...对于文章中提到的三种调用方式的异同点 ...
  • Ewasm智能合约在区块链价值性能高效:WASM采用二进制编码,在程序执行过程中性能优越;存储成本低:相对于文本格式,二进制编码文本占用存储空间更小;多语言支持:用户可以使用 C/C++/RUST/Go等多种语言编....
  • ETH——智能合约

    2020-10-07 02:35:04
    智能合约是以太坊精髓,也是以太坊和比特币最大一个区别。 什么是智能合约 智能合约是运行在区块链上一段代码, 代码逻辑定义了合约内容。 智能合约的账户保存了合约当前运行状态 balance:当前...
  • 交易必备方法和对象w3节点对象发送交易方法封装swapContract.pymain.pypython与以太坊智能合约交互需要做一个轮询脚本之前写了基于DYDX闪电贷在Cofix和Uniswap之间套利,只要解释了套利合约中逻辑以及怎么调用...
  • 1.erc20的标准和实现 2.erc721的标准和实现 3.erc721标准的改造 4.合约之间的调用和功能调试
  • 1.erc20的标准和实现 2.erc721的标准和实现 3.erc721标准的改造 4.合约之间的调用和功能调试
  • Solidity已经支持对未调用其他合同某些智能合约进行正式验证。当然,这不包括任何转让代币合约。 下面Solidity合同模拟了一个原始众筹合约,该合约可以持有Token,某些人可以根据其股份提取Token。它缺少...
  • 智能合约是介于区块链与业务系统之间,它是业务系统与区块链数据进行交互(设置,更新,获取数据)工具。 正常情况下区块链开发分为区块链底层开发和DAPP应用开发两大类,本节之前部署甚至定制开发都是链底层...
  • ABI是以太坊合约间相互调用的一种消息格式,包括从链外部调用链,或者合约之间的相互调用,类似于常见的rpc协议一样,也就是定义操作函数签名,参数编码,返回结果编码等。 1、函数 使用ABI协议的时候,必须要求在...
  • 智能合约在可执行代码中定义不同组织之间的规则。应用程序调用一个art contract来生成记录在分类帐上的事务。 我们可以使用区块链合同将这些程序转化为可执行的网络合同智能合约–开拓各种新的可能性。这是因为智能...
  • 1、智能合约的调用通信模型有内联调用和延迟调用。 2、action之间的执行完全独立,无法直接通信,如需在action间交互状态数据,则必须由一个action将数据写入EOSIO database(多索引表),再由另一个action从...
  • 1.erc20的标准和实现 2.erc721的标准和实现 3.erc721标准的改造 4.合约之间的调用和功能调试
  • 以太坊智能合约开发,Web3.js API 中文文档 ethereum web3.js入门说明 为了让你Ðapp运行上以太坊,一种选择是使用web3.js library提供web3。对象。底层实现上,它通过RPC 调用与本地节点通信。web3.js可以与...
  • 跨合约调用智能合约之间的调用本质上是外部调用,可以使用message call或者创建智能合约对象的形式进行调用。(1)使用message call比如合约1调用合约2的某个方法:bytes4 methodId = bytes4(keccak...
  • 智能合约之间的调用有四种方式 以太坊虚拟机 以太坊虚拟机,简称 EVM,是用来执行以太坊上的交易的。业务流程如下图: 输入一笔交易,内部会转换成一个 Message 对象,传入 EVM 执行。 如果是一笔普通转账交易,...
  • 区块链安全 - DAO攻击事件解析

    万次阅读 2018-03-05 19:52:48
    跨合约调用智能合约之间的调用本质上是外部调用,可以使用message call或者创建智能合约对象的形式进行调用。(1)使用message call比如合约1调用合约2的某个方法:bytes4 methodId = bytes4(keccak...
  • 在使用Solidity编写智能合约, 有时调用外部合约会使用委托调用,因为委托调用将执行逻辑交给了外部...但是需要注意是,委托调用时需要考虑委托合约和被委托合约之间状态变量对应关系,其底层就是插槽对应关系。

空空如也

空空如也

1 2 3 4
收藏数 74
精华内容 29
关键字:

智能合约之间的调用