solidity学习过程---msg

solidity 5.0,remix测试(个人学习,欢迎指正)

msg(研究了好一会,感觉还是有点困惑)

  1. msg.sender —当前合约的调用者
    (1) 部署合约的地址
    (2)调用该合约的地址
  2. msg.value —随消息发送的 wei 的数量(其实并不太懂)
    (1)随消息发送??? 什么类型的信息 ???
    (2) msg.value随消息发送 ,发送到哪儿?
    (3)在remix部署时,设置value,只要调用该命令之后,直接发送到账户余额 why????
    测试代码如下所示
pragma solidity >=0.4.21 <0.7.0;

contract TestMsgValue {

  address owner;
  uint fee = 32 wei;
  event MsgValue(uint);
  event Tansfer(address from, address to, uint count);

//如果不提前声明合约为payable 那么remix构造函数时将不能使用value赋予价值
   constructor() public payable {
     owner = msg.sender;
     /* emit MsgValue(msg.value); */
  }

  function show() public payable returns (uint) {
    /* require(msg.value >= fee);
    owner.transfer(msg.value - fee); */
     emit MsgValue(msg.value);
    /* emit MsgValue(msg.value); */

  }
  function getBalance() public view returns (uint)  {
    return address(this).balance;
  }
  function transferValue(address getValueAddress, uint count) public  {
    emit Tansfer(address(this), msg.sender, count);
    msg.sender.transfer(count);
    getBalance();
  }

}

测试说明

  1. 如果不声明构造函数 payable 就会报错如下图
    在这里插入图片描述
    我暂时理解为----如果不将这个合约payable,那么合约在部署时,并不具有接受以太币的条件(感觉不太对)。
  2. 部署合约时,带入value值,只要调用合约函数,那么value自动进入合约地址,this.balance += value;
    对于这个霸道操作不是很明白,为什么只要运行函数,操作该合约就会将value加入合约!难道我设置value之后,调用函数也是message,相应value就是其附带的值嘛?

当前进度思考

  1. 如果部署到以太坊上,这个实际过程是怎么样的?
  2. 可以通过函数直接对合约账户充值嘛?
  3. 测试deposit函数

值得记录的一些语法

  1. 比较相同
    (1)abi.encode() …returns (bytes) 对给定参数进行编码
    (2)abi.encodePacked() returns (byetes) 更加精确的方法计算调用数据
    keccak256(abi.encodePacked(a, b)) 取代了keccak256(a, b);

  2. view 与event

如果函数声明为 view 类型,这种情况下要保证不修改状态。

		下面的语句被认为是修改状态:
		修改状态变量。
		**产生事件**。 ----view 限制符下 event会失效!!
		创建其它合约。
		使用 selfdestruct。
		通过调用发送以太币。
		调用任何没有标记为 view 或者 pure 的函数。
		使用低级调用。
		使用包含特定操作码的内联汇编。
  1. this直接用作地址报错 (sol 5.0)
Invalid type for argument in function call. Invalid implicit conversion from contract TestMsgValue to address requested.
emit Tansfer(this, msg.sender, count);

解决方法: 显示类型转换address(this)

再次更新 2020.2.23
  1. 不通过remix设置value,直接初始化一个含有固定数量wei的合约;

这是在官方文档上找到的,现在已经不能使用了;

pragma solidity ^0.4.0;

contract B {
    function B() public payable {}
}

contract A {
    address child;

    function test() public {
        child = (new B).value(10)(); //construct a new B with 10 wei
    }
}

基于solc 5.0的代码 测试通过

pragma solidity >=0.5.0 <0.7.0;

contract D {
    uint x;
    constructor(uint a) public payable {
          x = a;
      }
      function getX() public  view returns (uint) {
        return x;
      }
      function  getBalance() public  view returns (uint) {
        return address(this).balance;
      }
}

contract C {
    D d ;
    event getDAddress(D);
    /* event getBalance(uint); */
    constructor() public {
        emit getDAddress(d);
        d = new D(4); // 将作为合约 C 构造函数的一部分执行
        emit getDAddress(d);
    }

    function createD(uint arg) public {
        D newD = new D(arg);
        emit getDAddress(newD);
    }
    function createAndEndowD(uint arg, uint amount) public payable {
                //随合约的创建发送 ether
        D newD = (new D).value(amount)();
          emit getDAddress(newD);
    }

    function  getbalance(D _d) public view returns (uint) {
      return  _d.getBalance();
    }
    function getX(D _d) public view returns (uint) {
      return _d.getX();
    }
    function getBalance() public view returns (uint) {
      return address(this).balance;
    }
}

	(1)首先申明一个合约D变量,在部署C合约的时候,那么在部署C合约的时候,就会自动创建D合约实例对象
	(2)并且通过createAndEndowD函数传入参数,(转入合约D),这样D合约就会存放一定数量的wei
	(3)调用createAndEndowD函数时,预设置value值,(要不然会报错---没有存入,就不能转账)
	(4)通过getBalance()可以获取C合约的账户余额,通过getbalance()可以获取到D合约的账户余额(地址可以通过event事件获得)
  1. msg.value确实会出发命令将预设置的值传递进入合约;(remix环境中,预设置value值,下一条命令的执行就会将值转入合约内部) ---- 正式环境使用待补充
发布了6 篇原创文章 · 获赞 1 · 访问量 179

猜你喜欢

转载自blog.csdn.net/qq_35434814/article/details/104453133
今日推荐