为了账号安全,请及时绑定邮箱和手机立即绑定

震惊!我在慕课网居然入门了区块链~

区块链的历史

Underground organization : Cypherpunk(密码朋克)

What are we talking about? 数学,加密技术,计算机,数字货币

  • 维基解密的创始人阿桑奇
  • BT下载的作者的布莱姆-科恩
  • WWW的发明者蒂姆伯纳斯-李
  • 智能合约概念的提出者:尼克萨博
  • Facebook创始人:肖恩帕克
  • 中本聪
  • Adam Back 发明Hashcash,使用了POW
  • Haber/Stornetta 提出时间戳方法保证数字文件安全的协议
  • 戴伟发明了B-money,强调点对点交易和不可更改记录
  • 哈尔-芬尼推出了“加密现金”
  • 2008年中本聪《比特币:一个点对点的电子现金系统》
  • 应用场景
    • 资产:数字资产发行、支付(跨境支付)、交易、结算
    • 记账:股权交易、供应链金融、商业积分
    • 不可篡改:溯源、众筹、医疗证明、存在性证明
    • 点对点:共享经济,物联网
    • 隐私:匿名交易
  • 优点
    - 财产只受自己控制
    - 无通胀
    - 没有假钞
    - 流通性好

账本如何验证?

  • 哈希函数:Hash(原始信息) = 摘要信息
  • 同样的原始信息用同一个哈希函数总能得到相同的摘要信息
  • 原始信息任何微小的变化都会哈希出面目全非的摘要信息
  • 从摘要信息无法逆向推算出原始信息

图片描述

账号所有权问题

密码->私钥 非对称加密技术(交易签名)
签名和验证是逆运算:付款地址是公钥,签名对摘要进行加密,验证是解密(用付款方地址和签名信息解密)的过程,然后得到交易摘要

补充:没有个人隐私,所以也就无法泄露隐私。安全(不泄露私钥)

图片描述

为什么记账?

  • 记账: Hash打包过程
  • 消耗资源
  • 奖励

图片描述

共识机制

两个节点同时完成工作量证明,使用谁的区块?

  • 无仲裁机构裁决
  • 都说用我的区块

为什么要遵守协议?

  • 节点工作量只有在其他的节点认同时其才是有效的
  • 累计工作量最大的区块链(独立,延长最长链)
  • 工作量证明+最长链 = 使用区块

图片描述

POW:工作量证明

课下迷思?

  • 比特币P2P网络,各个节点之间如何通信(点对点)?
  • 区块结构Merkle树
  • 比特币UTXO及交易脚本(Unspent Transaction Output未花费过的交易输出)
  • 比特币白皮书

区块链技术核心原理实现

不重复了,大家可以看边看视频边看讲师的博客https://learnblockchain.cn/2017/10/27/build_blockchain_by_python/

智能合约编程语言-solidity

文件结构

图片描述

pragma solidity ^0.4.20;

contract MyToken {
    mapping (address => uint256) public balanceOf;

    constructor(uint256 initialSupply) public {
        balanceOf[msg.sender] = initialSupply;              // Give the creator all initial tokens
    }

    function transfer(address _to, uint256 _value) public {
        require(balanceOf[msg.sender] >= _value);           // Check if the sender has enough
        require(balanceOf[_to] + _value >= balanceOf[_to]); // Check for overflows
        balanceOf[msg.sender] -= _value;                    // Subtract from the sender
        balanceOf[_to] += _value;                           // Add the same to the recipient
    }
}

数据类型

  • 状态变量 无符号整形uint
  • 函数 function setA(uint x) public { a = x; }
  • 事件 event Set_A(uint a); 调用事件 emit Set_A(x);
  • 结构 struct Pos { int lat; int lng;}
  • 函数修改器 modifier owner () {} 修饰函数 function mine() public owner{} 在mine函数执行前执行owner中的内容

值类型 Value Type

图片描述

引用类型(Reference Types)

图片描述

全局变量和函数

  • 有关区块和交易
    • msg.sender(address)
    • msg.value(uint)
    • block.coinbase(address)
    • block.difficulty(uint)
    • block.number(uint)
    • block.timestamp(uint)
    • now(uint)
    • tx.gasprice(uint)
  • 有关错误处理
  • 有关数字及加密功能
  • 有关地址和合约

错误处理

程序发生错误时的处理方式:solidity的处理方式是回退状态
相关函数:assert(内部逻辑错误),require(外部错误)

发送一半的值
pragma solidity A0.4.20;

contract Sharer{

function sendHalf(address addr)public payable returns (uint balance){

require(msg.value %2==0);

uint balanceBeforeTranfer=this.balance;

addr.transfer(msg.value/2);

assert(this.balance==balanceBeforeTranfer-msg.value/2);

return this.balance;

}


参数

  • 输入参数
  • 输出参数
  • 命名参数 {} 类似python
  • 参数解构 元素的值可以赋值给多个变量
contract Test{

function simpleInput(uint a,uint b)

public constant returns (uint sum,uint mul){

sum=a+b;

mul=a*b;

function testSimpleInput()

public constant returns (uint sum,uint mul){

(sum,mul)=simpleInput({ b:3,a:1});

function f()public constant returns (uint,bool,uint){

return (7,true,2);

function g) public {
	var (x,y,z) = f();
	(x,z) = (z,x);
	只取y和z的值
	(,y,z) = f();
	(x,) = (1,);
}

控制结构

没有switch goto,其他都有

可见性

public

公开函数是合约接口的一部分,可以通过内部,或者消息来进行调用。对于public类型的状态变量,会自动创建一个访问器。函数默认可见性public

private

私有函数和状态变量仅在当前合约中可以访问,在继承的合约内,不可访问。

external

外部函数是合约接口的一部分,只能使用消息调用
在同一个合约中可以使用this(消息调用)来调用
如果我们只接收外部调用的话,我们应该使用external
internal
函数和状态变量只能通过内部访问。如在当前合约中调用,或继承的合约里调用。状态变量默认的可见性是internal
不能在其他的合约中调用

函数

  • 构造函数
  • 视图函数(constant/view(优先)) 不会修改状态变量
  • 纯函数(pure) 不读取变量,也不修改变量
  • 回退函数 无名函数,被动调用函数
  • 其实public也是一个函数,因为会自动创建一个访问器
contract Test{

uint internal data;

constructor (uint a)public{

data=a;

event EVENTA(uint a);

function testView()public view returns(uint){
	//data=1;
	// emit EVENTA(1);
	return data;
	}

function f()public pure returns(uint){
	return 1*2;
	}

有另一个合约向Test合约转账,就需要下面的callback函数
function ()public payablel{
	}
}
contract Caller {
	function callTest(Test test) public {
	 test.send(ether);
	 }
 }


区块链去中心化应用开发

简单代币合约

pragma solidity ^0.4.20;

contract MyToken {
	保存每一个账户的余额情况
    mapping (address => uint256) public balanceOf;

    constructor(uint256 initialSupply) public {
	    把余额给创建者
        balanceOf[msg.sender] = initialSupply;              // Give the creator all initial tokens
    }
	代币转移
    function transfer(address _to, uint256 _value) public {
        require(balanceOf[msg.sender] >= _value);           // Check if the sender has enough
        require(balanceOf[_to] + _value >= balanceOf[_to]); // Check for overflows
        balanceOf[msg.sender] -= _value;                    // Subtract from the sender
        balanceOf[_to] += _value;                           // Add the same to the recipient
    }
}

标准代币合约

这个是根据20版本来写的,当时是最新版,现在已经更新到

pragma solidity ^0.4.20;

contract ERC20Interface {
  string public name;
  string public symbol;
  uint8 public  decimals;
  uint public totalSupply;


  function transfer(address _to, uint256 _value) returns (bool success);
  function transferFrom(address _from, address _to, uint256 _value) returns (bool success);
  function approve(address _spender, uint256 _value) returns (bool success);
  function allowance(address _owner, address _spender) view returns (uint256 remaining);
交易发生时的事件
  event Transfer(address indexed _from, address indexed _to, uint256 _value);
  委托行为发生时的事件
  event Approval(address indexed _owner, address indexed _spender, uint256 _value);

}

contract ERC20 is ERC20Interface {

    mapping (address => uint256) public balanceOf;
    mapping (address => mapping (address => uint256)) internal allowed;

    constructor() public {
        totalSupply = 100000000;
        name = "MUKE Token";
        symbol = "IMOOC";
        decimals = 0;
        balanceOf[msg.sender] = totalSupply;
    }

  function balanceOf(address _owner) view returns (uint256 balance) {
      return balanceOf[_owner];
  }

    function transfer(address _to, uint _value) public returns (bool success) {
        require(_to != address(0));
        require(_value <= balanceOf[msg.sender]);
        require(balanceOf[_to] + _value >= balanceOf[_to]);

        balanceOf[msg.sender] -= _value;
        balanceOf[_to] += _value;
        emit Transfer(msg.sender, _to, _value);
        return true;
    }

      function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        require(_to != address(0));
        require(_value <= balanceOf[_from]);
        require(_value <= allowed[_from][msg.sender]);
        require(balanceOf[_to] + _value >= balanceOf[_to]);

        balanceOf[_from] -= _value;
        balanceOf[_to] += _value;

        allowed[_from][msg.sender] -= _value;
        emit Transfer(_from, _to, _value);
        return true;
      }
  允许另外一个人操作我的账户	
  function approve(address _spender, uint256 _value) returns (bool success) {
          allowed[msg.sender][_spender] = _value;
    emit Approval(msg.sender, _spender, _value);
    return true;
  }
  查询被委托了多少个代币
  function allowance(address _owner, address _spender) view returns (uint256 remaining) {
      return allowed[_owner][_spender];
  }

}

 npm i -g truffle
 truffle init
 

合约部署

var Adoption = artifacts.require("Adoption");

module.exports = function(deployer) {
  deployer.deploy(Adoption);
};

配置truffle
执行命令 truffle migrate

合约测试用例

pragma solidity ^0.4.17;

import 'truffle/Assert.sol';
import 'truffle/DeployedAddresses.sol';
import '../contracts/Adoption.sol';

contract TestAdoption {
    拿到测试合约
    Adoption adoption = Adoption(DeployedAddresses.Adoption());
	判断是否可以领养宠物
    function testUserCanAdoptPet() public {
        uint returnedId = adoption.adopt(8);
        uint expected = 8;
        Assert.equal(returnedId, expected, "Aoption of pet Id 8 should be recorded.");
    }
	// 测试领养地址
    function testGetAdopterAddressByPetid() public {
        address expected = this;
        address adopter = adoption.adopters(8);

        Assert.equal(adopter, expected, "Owner of pet ID 8 should be recorded.");
    }
    // 测试所有的领养者
    function testGetAdopterAddressByPetIdInArray() public {

        address expected = this;

        address[16] memory adopters = adoption.getAdopters();
        Assert.equal(adopters[8], expected, "Owner of Pet Id 8 should be recoded.");
    }
}


点击查看更多内容
14人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消