建议和反馈

请填写你的反馈内容

感谢您对链客的信任!

恭喜您填写完个人简历!链客专注于区块链职位连接,帮助您的投递更加精准高效,赶快去选择自己心仪的岗位吧!

推动中国区块链事业发展始终是我们坚定不移的梦——链客团队

Remix使用与代码调试

2018-07-30 15:55:50

常用solidity编辑器

Remixd:与本地共享目录

1.在线的remix可以共享本地目录

->npm inatall remixd -g

->remixd -s <shared folder>

 

2.本地remixd

->npm install remix-ide

->remix-ide

 

3.Remix-app

 

4.使用编译器其他插件


打开在线IDE remix

http://remix.ethereum.org

新增一个命名为“HelloWorld.sol”的文件:

pragma solidity ^0.4.17;

contract Hello         
{
    address creator;     
    string greeting;     

    function Hello(string _greeting) public   
    {
        creator = msg.sender;
        greeting = _greeting;
    }    

    function greet() public constant returns (string)           
    {        return greeting;
    }    
    function setGreeting(string _newgreeting) public
    {
        greeting = _newgreeting;
    }    
     /**********
     Standard kill() function to recover funds 
     **********/
    
    function kill() public
    { 
        if (msg.sender == creator)
            suicide(creator);  // kills this contract and sends remaining funds back to creator
    }

}

点击"Start to compile"按钮,会得到一下结果:

0.智能合约编译.png


除一些函数的告警提示外,结果表明该智能合约编译成功。

2.1.1 编译告警

如果编写的程序有告警,REMIX会有提示。一般来说,提示不必修改。

REMIXD编译告警

2.1.2 编译错误

为了说明编译错误案例,把该文件的第17行"return greeting;"改为"return _greeting;", 重新编译,得到以下结果

REMIXD编译错误

如果编写的Solidity程序存在语法错误,Remix编译器会以粉红色底色提示显示错误原因,并在编辑器窗口提示位置。
编译错误演示完后,恢复第17行代码为"return greeting;"

2.1.3 详情信息

点击"Detail"按钮,可以看到详细信息。其中WEB3DEPLOY部分的内容就是在案例《第二课 如何实现以太坊最简智能合约“Hello World”的运行》中geth控制台使用的编译后代码。

DETAIL的内容

2.2 智能合约运行

1. 创建智能合约
选择“Run”的页面,选择Environment环境为Javascript VM,在“Create”按钮前输入框内输入"Hello World!"[注意:输入字符串一定要有英文双引号],点击“Create”按钮。

创建智能合约


2. 运行greet函数
点击浅蓝色函数"greet"按钮,可以看到输出结果为“Hello World!”

运行函数greet


说明:浅蓝色按钮函数表示该交易函数运行时不需要消耗GAS的。

3. 运行setGreeting函数
在setGreeting函数按钮的输入框输入内容"Hello Duncan!", 运行后在点击执行"greet"函数,发现该函数的输出内容已变为"Hello Duncan!"了,说明setGreeting执行正常。

运行函数SetGreeting


说明:粉红色按钮函数表示该交易函数运行时是需要消耗GAS的。

3. REMIX界面详解

第2章以“Hello World”为例,介绍了REMIX集成环境的基本使用方法。本章介绍REMIX编辑器的详细功能描述。

3.1 REMIX集成环境概述

REMIX是一个智能合约编程语言Solidity的集成开发环境,它集成了一个调试器和测试环境。
如果你对以下内容感兴趣,REMIX是一个不错的学习方式:
1,开发智能合约(REMIX集成了SOLIDITY编辑器)
2,调试智能合约
3,获取已运行合约的状态和属性
4,调试已经提交的合约
5,分析SOLIDITY代码,以便减少编码错误和加强最佳实践
6,配合Mist(或者任何植入web3的工具),REMIX可用于测试和调试DAPP分布式程序。(参考链接Debugging a Dapp using Remix - Mist - Geth )
详解介绍使用的程序案例为"ballot.sol"文件的代码,完整代码如下:

pragma solidity ^0.4.0;
contract Ballot {

    struct Voter {
        uint weight;
        bool voted;
        uint8 vote;
        address delegate;
    }
    struct Proposal {
        uint voteCount;
    }

    address chairperson;
    mapping(address => Voter) voters;
    Proposal[] proposals;    /// Create a new ballot with $(_numProposals) different proposals.
    function Ballot(uint8 _numProposals) public {
        chairperson = msg.sender;
        voters[chairperson].weight = 1;
        proposals.length = _numProposals;
    }    /// Give $(toVoter) the right to vote on this ballot.
    /// May only be called by $(chairperson).
    function giveRightToVote(address toVoter) public {        if (msg.sender != chairperson || voters[toVoter].voted) return;
        voters[toVoter].weight = 1;
    }    /// Delegate your vote to the voter $(to).
    function delegate(address to) public {
        Voter storage sender = voters[msg.sender]; // assigns reference
        if (sender.voted) return;        while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender)
            to = voters[to].delegate;        if (to == msg.sender) return;
        sender.voted = true;
        sender.delegate = to;
        Voter storage delegateTo = voters[to];        if (delegateTo.voted)
            proposals[delegateTo.vote].voteCount += sender.weight;        else
            delegateTo.weight += sender.weight;
    }    /// Give a single vote to proposal $(toProposal).
    function vote(uint8 toProposal) public {
        Voter storage sender = voters[msg.sender];        if (sender.voted || toProposal >= proposals.length) return;
        sender.voted = true;
        sender.vote = toProposal;
        proposals[toProposal].voteCount += sender.weight;
    }    function winningProposal() public constant returns (uint8 _winningProposal) {
        uint256 winningVoteCount = 0;        for (uint8 prop = 0; prop < proposals.length; prop++)            if (proposals[prop].voteCount > winningVoteCount) {
                winningVoteCount = proposals[prop].voteCount;
                _winningProposal = prop;
            }
    }
}

REMIX主界面截图如下,具体说明参考各个子章节。

REMIX主界面截图


具体界面介绍章节分类如下:
3.2 文件浏览器
3.3 Solidity语言编辑器
3.4 终端输出器
3.5 分页控制面板
3.5.1 编译合同
3.5.2 运行
3.5.3 调试
3.5.4 设置
3.5.5 分析
3.5.6 支持

3.2 文件浏览器

文件浏览器


1)增加新文件(Create new File)
点击在浏览器上增加一个新的智能合约文件

9.增加新文件.png

2)打开文件(Add Local File)

打开存在文件


3) 匿名发布到GitHub(Publish to Gist)

11. 匿名发布到GitHub.png

4) 复制文件列表到其他浏览器(Copy to another instance)
例如,把“http://remix2.ju3ban.net”的文件列表复制到另一个浏览器“http://remix.ju3ban.net”
修改输入目标浏览器的网址:

12.复制到别的浏览器.png

打开新的浏览器,文件列表已复制过来了:

13.别的浏览器的文件列表.png

5)链接本地服务器(Connect to Localhost)
在Remix文件浏览器上的文件并不会同步到本地文件系统,对浏览器文件列表的新增/修改/删除并不会同步本地文件。一般操作时,调试成功的代码需要在本地文件系统新建文件保存。Remix浏览器提供了一种方法,就是使用Remixd,允许保存和同步浏览器文件到你的本地计算机中。因为根据官网文档,笔者没有能够在Windows 10系统或者Ubuntu中安装成功Remixd,本文不再详细介绍该功能。有兴趣的朋友欢迎根据官网文档尝试使用REMIXD同步。成功者欢迎跟辉哥反馈交流,补充完整这个文档。

14. 链接本地文件系统.png

3.3 Solidity语言编辑器

15. Solidity 浏览器.png

Solidity语言编辑器重要的功能列表:
1,TAB页面显示打开的文件
2,编译告警或者错误会显示在编辑器最左侧边
3,Remix自动保存当前文件(修改后5秒内)
4,+/- 表示增加/减少编辑器的字体大小

3.4 终端输出器

终端输出器窗口

终端输出器功能说明:
1,点击1按钮可隐藏终端输出器
2,点击2按钮可情况输出器内容
3,点击3按钮可复制地址信息等到缓存,便于粘贴
4,点击Details按钮可展开交易详细内容
5, 点击Debug按钮可调试该交易合约
6, 点击复选框,可增加选择显示所有的交易还是只显示智能合约相关的交易程序。默认只显示后者。

17. 终端显示内容.png


7,输入关键字可搜索定位输出内容
例如输入"Hello "关键字,相关的内容就显示出来了。

18. 搜索Hello关键字


8,监听网络(Listen to network)
勾选后,REMIX不仅监听REMIX编辑器中创建的交易,还监听当前环境中所有的交易。

3.5 分页控制面板

3.5.1 编译合约

20. Compile控制面板.png

1,发布到Swarm网络(Publish on Swarm)
点击“Publish on Swarm”按钮可把智能合约源码和对应的ABI信息发布到网络上。这个合约智能是非抽象类的才能发布。
合约发布后,你可以点击Detail按钮,在弹出窗口的“SWARM LOCATION”
位置找到对应的MetaDATA信息。
信息中的SWARM LOCATION位置有对应网址,在能科学上网的计算机就可找到该合同的MetaData信息 “bzzr://165fad4c3d8ead3a7fe28296777b4bedafb09bb57de2e9ba39c1547866437182”

3.5.2 运行

21. Run控制面板.png

重点特性说明
1) 环境选择
JavaScript VM: 所有交易在浏览器的沙盒中被执行。这以为着没有结果是永久保存的。当页面重载后,一个新的区块链会被从零开始运行,老的会被丢弃。
Injected Provider: Remix将连接被植入的Web3对象。例如Mist或者Metamask钱包是提供植入的Web3对象的例子。例如《第八课 如何调试以太坊官网的智能合约众筹案例》就是使用Meta的账号。
Web3 Provider: Remix将连接到一个远程节点。你可以用这个地址来选择钱包客户端:geth, parity or any Ethereum client.

赞赏(0)

收藏(0)

阅读(1143)

评论(0)问答(0)
请先登录或注册

请先登陆或注册

推荐阅读

笔记:支持追加发币和暂停交易的ERC20智能合约

修修改改,又在测试链上测了一通,感觉没问题了pragma solidity ^0.4.24; /** * @title SafeMath * @dev Math operations with safety checks that throw on error */ library SafeMath { /** * @dev Multiplies two numbers, throws on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { if (a == 0) { return 0; } c = a * b; assert(c / a == b); return c; } /** * @dev Integer division of two numbers, truncating the quotient. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } /** * @dev Adds two numbers, throws on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256 c) { c = a + b; assert(c >= a); return c; } } /** * @title ERC20Basic * @dev Simpler version of ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/179 */ contract ERC20Basic { uint256 public totalSupply; function balanceOf(address who) public view returns (uint256); function transfer(address to, uint256 value) public returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); } /** * @title ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/20 */ contract ERC20 is ERC20Basic { function allowance(address owner, address spender) public view returns (uint256); function transferFrom(address from, address to, uint256 value) public returns (bool); function approve(address spender, uint256 value) public returns (bool); event Approval(address indexed owner, address indexed spender, uint256 value); } /** * @title Basic token * @dev Basic version of StandardToken, with no allowances. */ contract BasicToken is ERC20Basic { using SafeMath for uint256; mapping(address => uint256) balances; /** * @dev transfer token for a specified address * @param _to The address to transfer to. * @param _value The amount to be transferred. */ function transfer(address _to, uint256 _value) public returns (bool) { require(_to != address(0)); require(_value <= balances[msg.sender]); uint previousBalances = balances[msg.sender] + balances[_to]; // SafeMath.sub will throw if there is not enough balance. balances[msg.sender] = balances[msg.sender].sub(_value); balances[_to] = balances[_to].add(_value); emit Transfer(msg.sender, _to, _value); assert(balances[msg.sender] + balances[_to] == previousBalances); return true; } /** * @dev Gets the balance of the specified address. * @param _owner The address to query the the balance of. * @return An uint256 representing the amount owned by the passed address. */ function balanceOf(address _owner) public view returns (uint256 balance) { return balances[_owner]; } } /** * @title Standard ERC20 token * * @dev Implementation of the basic standard token. * @dev https://github.com/ethereum/EIPs/issues/20 * @dev Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol */ contract StandardToken is ERC20, BasicToken { mapping (address => mapping (address => uint256)) internal allowed; /** * @dev Transfer tokens from one address to another * @param _from address The address which you want to send tokens from * @param _to address The address which you want to transfer to * @param _value uint256 the amount of tokens to be transferred */ function transferFrom(address _from, address _to, uint256 _value) public returns (bool) { require(_to != address(0)); require(_value <= balances[_from]); require(_value <= allowed[_from][msg.sender]); uint previousBalances = balances[_from] + balances[_to]; balances[_from] = balances[_from].sub(_value); balances[_to] = balances[_to].add(_value); allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value); emit Transfer(_from, _to, _value); assert(balances[_from] + balances[_to] == previousBalances); return true; } /** * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. * * Beware that changing an allowance with this method brings the risk that someone may use both the old * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * @param _spender The address which will spend the funds. * @param _value The amount of tokens to be spent. */ function approve(address _spender, uint256 _value) public returns (bool) { allowed[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); return true; } /** * @dev Function to check the amount of tokens that an owner allowed to a spender. * @param _owner address The address which owns the funds. * @param _spender address The address which will spend the funds. * @return A uint256 specifying the amount of tokens still available for the spender. */ function allowance(address _owner, address _spender) public view returns (uint256) { return allowed[_owner][_spender]; } /** * approve should be called when allowed[_spender] == 0. To increment * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) */ function increaseApproval(address _spender, uint _addedValue) public returns (bool) { allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue); emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true; } function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) { uint oldValue = allowed[msg.sender][_spender]; if (_subtractedValue > oldValue) { allowed[msg.sender][_spender] = 0; } else { allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue); } emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true; } } /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". */ contract Ownable { address public owner; /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ constructor() public{ owner = msg.sender; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(msg.sender == owner); _; } } /** * @title Pausable * @dev Base contract which allows children to implement an emergency stop mechanism. */ contract Pausable is Ownable { event Pause(); event Unpause(); bool public paused = false; /** * @dev Modifier to make a function callable only when the contract is not paused. */ modifier whenNotPaused() { require(!paused); _; } /** * @dev Modifier to make a function callable only when the contract is paused. */ modifier whenPaused() { require(paused); _; } /** * @dev called by the owner to pause, triggers stopped state */ function pause() onlyOwner whenNotPaused public { paused = true; emit Pause(); } /** * @dev called by the owner to unpause, returns to normal state */ function unpause() onlyOwner whenPaused public { paused = false; emit Unpause(); } } /** * @title Mintable token * @dev Simple ERC20 Token example, with mintable token creation * Based on code by TokenMarketNet: https://github.com/TokenMarketNet/ico/blob/master/contracts/MintableToken.sol */ contract MintableToken is StandardToken, Pausable { event Mint(address indexed to, uint256 amount); event MintFinished(); bool public mintingFinished = false; modifier canMint() { require(!mintingFinished); _; } modifier hasMintPermission() { require(msg.sender == owner); _; } /** * @dev Function to mint tokens * @param _to The address that will receive the minted tokens. * @param _amount The amount of tokens to mint. * @return A boolean that indicates if the operation was successful. */ function mint( address _to, uint256 _amount ) hasMintPermission canMint public returns (bool) { totalSupply = totalSupply.add(_amount); balances[_to] = balances[_to].add(_amount); emit Mint(_to, _amount); emit Transfer(address(0), _to, _amount); return true; } /** * @dev Function to stop minting new tokens. * @return True if the operation was successful. */ function finishMinting() onlyOwner canMint public returns (bool) { mintingFinished = true; emit MintFinished(); return true; } } /** * @title Burnable Token * @dev Token that can be irreversibly burned (destroyed). */ contract BurnableToken is MintableToken { event Burn(address indexed burner, uint256 value); /** * @dev Burns a specific amount of tokens. * @param _value The amount of token to be burned. */ function burn(uint256 _value) public { _burn(msg.sender, _value); } function _burn(address _who, uint256 _value) internal { require(_value <= balances[_who]); // no need to require value <= totalSupply, since that would imply the // sender's balance is greater than the totalSupply, which *should* be an assertion failure balances[_who] = balances[_who].sub(_value); totalSupply = totalSupply.sub(_value); emit Burn(_who, _value); emit Transfer(_who, address(0), _value); } } /** * @title Pausable token * @dev StandardToken modified with pausable transfers. **/ contract PausableToken is BurnableToken { function transfer( address _to, uint256 _value ) public whenNotPaused returns (bool) { return super.transfer(_to, _value); } function transferFrom( address _from, address _to, uint256 _value ) public whenNotPaused returns (bool) { return super.transferFrom(_from, _to, _value); } function approve( address _spender, uint256 _value ) public whenNotPaused returns (bool) { return super.approve(_spender, _value); } function increaseApproval( address _spender, uint _addedValue ) public whenNotPaused returns (bool success) { return super.increaseApproval(_spender, _addedValue); } function decreaseApproval( address _spender, uint _subtractedValue ) public whenNotPaused returns (bool success) { return super.decreaseApproval(_spender, _subtractedValue); } } /** * @title RPHToken Token * * @dev Implementation of RPHToken Token based on the basic standard token. */ contract RPHToken is  PausableToken{ function () public { //if ether is sent to this address, send it back. revert(); } /** * Public variables of the token * The following variables are OPTIONAL vanities. One does not have to include them. * They allow one to customise the token contract & in no way influences the core functionality. * Some wallets/interfaces might not even bother to look at this information. */ string public name; uint8 public decimals=18; string public symbol; string public version = '1.0.0'; /** * @dev Function to check the amount of tokens that an owner allowed to a spender. * @param _totalSupply total supply of the token. * @param _name token name e.g RPHT Token. * @param _symbol token symbol e.g RPHT. */ constructor(uint256 _totalSupply, string _name, string _symbol) public { totalSupply = _totalSupply * 10 ** uint256(decimals); balances[msg.sender] = totalSupply;    // Give the creator all initial tokens name = _name; symbol = _symbol; } }
全村首富,月薪50元  ·  2018-08-08
1768阅读  ·  16赞赏  ·   0问答

区块链笔记 共识理解+椭圆曲线加密

一,区块链基础《比特币白皮书》http://www.8btc.com/wiki/bitcoin-a-peer-to-peer-electronic-cash-system《以太坊白皮书》https://ethfans.org/posts/ethereum-whitepaper《精通比特币》http://book.8btc.com/master_bitcoin《腾讯区块链方案白皮书》http://www.cbdio.com/BigData/2017-04/25/content_5503014.htm1.什么是区块链?答:区块链是一种去中心化的分布式数据库。任何人只要架设自己的服务器,接入区块链网络,都可以成为这个庞大网络的一个节点。区块链本质就是数据库,基本单元为区块。2.区块链技术都能做那些领域的工作答:基于区块链本身的特性,区块链内部由于hash的存在,区块内部数据是无法篡改的。又因为运用了非对称加密技术,所以在节点间交易也很安全,加上区块链的本质,交易也不会用到第三方的介入。所以大概能运用到一下几个领域:1)金融领域-----------用到区块链的技术公开和不可篡改性。例如:跨境支付,保险理赔,正确,票据2)物联网领域---------中心化的大型服务器维护费用高昂,链技术会大量降低成本。例如:租房等3)公共服务领域-------建立不可篡改的数字化证明。例如:数字版权,知识版权,证书等4)公益慈善领域--------不可篡改性。例如:慈善机构的项目,明细,资金流向等5)供应链领域-------不可篡改,产品防伪,交易追溯。例如:解决供应链纠纷,根除供应链内产品流转过程中的假冒位列问题3.区块链的特点答:去中心化。可溯源,不可篡改,公开透明。4.你了解过区块的技术结构么?答:这个问题的话,我自己用java吧,写了个稍微简单一点的比特币区块链系统,很明白这个。在区块中的数据结构是这样的,他基本分为区块头和区块体,主要变量包括,本区块的hash,上一区块的hash,时间戳,数据,难度,默克尔根信息等等。区块头里只有hash和一个随机数nonce值。区块与区块之间用hash进行连接。然后在各种验证方法下,就可以确保区块链的顺利进行。二,区块链进阶1.主流的共识算法答:有POW,POS,DPOS等。1)PoW英语为proof of work,工作量证明。是中本聪率先使用的共识机制,它通过各个节点的算力比拼,从而在哪个节点来执行挖矿的问题上达成共识。具体细说的话就是:在比特币中,每一个区块的区块头里有一个Nonce随机数,节点是这样计算的,当节点对区块头里hash+nonce这个数进行双重SHA256运算,如果算的值小于目标值的时候,此时的随机数nonce就算是工作量证明。并向全网广播。刚才说的目标值和难度的问题,我可以举个小例子来解释,为什么双重hash计算后的值要小于目标值。就如同打麻将扔骰子一样,如果你有两个骰子,让你不停地扔,两个骰子的点数之和小于10的概率是不是比小于5的概率要大很多。所以说,目标值越小,概率就越小。就在此时,给你了五个筛子一起扔,是不是扔出点数之和小于5的概率就更加小了。说到底,PoW的意义还是跨时代的,但是也会出现很多问题。比如说,大量算力的浪费,或者出现巨大的算力中心,这都与区块链技术的去中心化不相符合。2)基于PoW的各种不足,出现了PoS--Proof of Stake 权益证明。PoS通过消耗币龄从而铸币。即,你的财富越大,存放时间越长,你的币龄或者说你的权益就更大,这样你就与其他节点达成共识,你就拥有了下一个区块铸币的权利,消耗掉你所有的币龄,并获得奖励。POS保留了POW作为铸币流程的初始部分以促进初始铸币,但是作用类似于股票交易的上市首发,之后就不需要POW机制进行铸币了。但是,与POW不同的是,币权交易的哈希操作是在一个有限的搜索内执行(更具体地说,是每秒在每个未支付的钱包进行一次hash),而不是像POW那样在一个无限的搜索空间内进行,因此不需要消耗大量的能源。另外,POS的哈希目标是连续调整的,不像比特币有两周的调整间隔,可以避免网络产出率的突然波动。POS保留了POW作为铸币流程的初始部分以促进初始铸币,但是作用类似于股票交易的上市首发,之后就不需要POW机制进行铸币了。但可是,PoS也有他的不足。即财富中心!拥有巨大财富的节点,将会拥有更多的权益用来铸币,必然会导致“富者越富,穷者更穷”的马太效应。即持有数字货币权益越多得人,他创建新区快的可能性更高。而穷人由于初始权益很少,币龄不足,获得创建区块的可能性大为降低了。3)应运而生的DPoS----Delegated Proof of Stake。中文:授权股权证明机制。现今使用DPoS的代表就是比特股了,基于比特股来说,DPoS与POS最大的不同在于,铸币权不再是由系统根据特定算法随机选出,而是由网络的全部节点基于权益随机投票选出101位授权委托代表,由这101位代表进行铸币以及维护网络安全。POS机制下,每一个持有数字币的钱包拥有权益,可以确认交易、参与铸币以及赢得数字币。DPOS机制下,每一个持有数字币的账户可以投片选出代表,由这101位代表(比特股系统中设置的是101位代表)来完成确认交易、维护区块链以及获取交易费用的功能。股东投票给见证人的过程充分体现了去中心化的特点。DPoS的工作机理是这样子的:1.每一个持有数字货币的账户类似于股份公司的股东,它可以投票选择任意数量的见证人(即代表,delegate)来产生区块。2.每个股东(账号)可以投票给一位见证人,最终得票数最高的前n位见证人被系统选中担任代表。(此代表的数目为:至少有50%的投票股东认为已经充分中心化所需的数量。例如比特股中就设置了101名代表)此投票过程充分体现了去中心化的特点。不足之处那就是选民对投票漠不关心,一些小规模的数字币持有者对于投票并不积极,因为即使投票选举了符合自己意愿的代表,但是代表在执行其职责期间所做的决定对只持有者的利益没有什么影响,所以小规模权益持有者不愿意话费太多精力来关注精选代表。如果,小规模持有者的参与程度不足,很有肯能导致一些大规模持有者控制了授权代表的选举,他们也会投票选择自己来担任授权代表,这必然影响到“去中心化”的实现。所以说,并不存在绝对好的共识算法,要根据需要适当的去选取和设计自己共识算法。2.密码学一般用的比较多的就是RSA,MD5还有就是椭圆曲线加密。我对这个椭圆曲线加密,有点了解。我给您说说。比特币系统中的椭圆曲线加密算法,在其数学原理的基础上,充分应用了椭圆曲线加密算法的单向特性,在区块链的钱包中,私钥可以产生出公钥,而反过来要想从公钥推算出私钥则不可能;用公钥加密的信息,可以用私钥来解密;而用私钥签名的信息,则由公钥来验证,验证通过后说明该信息确实为私钥持有人所发布。1)先说椭圆曲线的特性。这个涉及到数学问题和椭圆曲线的数学原理,椭圆曲线的特性为:(1)所有椭圆曲线都基于X轴对称。(2)任何不平行与X轴的直线,与椭圆曲线最多有三个焦点。举例说明,椭圆曲线的加密数学原理(可以画出来):在去线上任意一点A作为基点,由基点出发向曲线上任意一点B打点(射线),如果有第三个交点,则取这个交点的关于X轴映射点C。再由基点A向此映射点C打点,如果有第三个交点,则继续去交点的X轴映射点D。直至没有第三个交点为止。看图可知A向E打点就没有第三个交点了。我们来设想一下。如果有个人窃取了点A的为止、曲线的形状、和最后点E的位置;但是不知道点B的位置。是不是也无法知道整个打点过程一共打过几次点,并且也不知道每一次打点的交点都在哪。以上就是椭圆曲线的特性。2)椭圆曲线在使用中的加密解密原理: 想知道的同学可以悄悄来问我,实在写不出来!3.Solidity以太坊智能合约开发https://ethereum.github.io/browser-solidity/#optimize=false&version=soljson-v0.4.24+commit.e67f0147.js   Remix IDE 智能合约测试网站  (删除源代码直接编写即可)4.以太坊私有链搭建教程:https://blog.csdn.net/xiabing082/article/details/771976075.IPFS6.trufflehttps://truffleframework.com/boxes/7.web3.js APIhttp://web3.tryblockchain.org/Web3.js-api-refrence.html  API文档三,区块链高级1.比特币:(1)java模拟一http://note.youdao.com/noteshare?id=cb23e91f748001b5ea8958356a2e5004&sub=527822ED8A704A1F8E043007E54EA6AC(2) java模拟二http://note.youdao.com/noteshare?id=03246a2aac26eb00894154c124c8fe58&sub=DE65B17D66B243639ED63C0A35E27914     (3)比特币/以太坊中,区块头里的Nonce值他是创建新区快的“钥匙”,当然钥匙是加了双引号的。以比特币为例,其工作原理如下:区块头及区块主体构建完成以后,挖矿也就是解数学题就可以开始进行了,挖矿的目标就是通过不断改变区块头中的Nonce值,使得对区块头使用SHA-256算法得出的哈希值符合难度值的要求。比特币挖矿的目标就是找到一个这样的nonce值,使得在这个值下的区块头的SHA-256哈希值的输出必须小于难度值中设定的值,矿工通过不停地变更区块头的随机数,即不断变更nonce的数值,并对每次变更后的区块头做双重SHA-256运算,即【SHA-256(SHA-256(Block_Header))】,将运算结果值与目前网络中的目标值做对比,如果小于目标值,则工作量证明完成,区块创建成功,该名矿工并会全网络广播这一Nonce值,经过其他矿工验证通过,即可获得全网络节点的认可,加入到区块链中成为行的区块,其他矿工则迅速以该区块作为福区块进行新的计算,并试图挖出新的区块。(4)比特币源码的seed()方法当中还有一个小nonce随机数。这个nonce只为了在挖矿方法里,同时启动五个线程,从五个随机数开始进行递增同时去挖矿。所以说这个小nonce随机数,与挖矿只有间接关系,没有什么直接关系!2.比特币和以太坊的区别(1)从定义上共同的定义是,比特币和以太坊都是成功的区块链技术应用,是最典型的代表。再细说点呢,有了比特币才有区块链技术,有了以太坊人们才认识到区块链还可以独立出来,不仅仅是比特币才能有区块链技术,也是以太坊为后面开启了区块链世界的思路思想。因为都是区块链技术的应用,所以底层基础思路是一样的。都是点对点的网络节点、公开的账本、共识基础算法,都是通过挖矿来维护网络。不同的定义是,比特币是点对点数字化支付系统,类似的是一家可以全球结算的银行,而这个银行是没有中心化组织成员的,没有CEO,没有管理员,只有代码和共识的基础原则。而这个银行的结算或者发行的货币就叫比特币,这叫银行也叫比特币。最主要的是银行的账本完全公开的,任何人查看每笔交易和记录都可以,而且每笔交易都可以追溯到源头,通过加密及数学魅力也实现了账本不可更改等特性。而且最大的特点,点对点价值传输,不需要其他第三方,或者信任机构。而以太坊的定义呢,是点对点的去中心化的虚拟机,虚拟机是干什么的,就有点像在阿里云买的服务器,各种环境已经配置好了,就等你按照开发框架和开发语言来编写自己的程序代码,把程序安装在这个虚拟机系统运行,如果是一台虚拟机和现在的也没太大区别,但是整个以太坊系统是可以由全球任何计算机加入到这个体系了,每台电脑只要安装了以太坊客户端就可以成为以太坊的一个节点一个虚拟机,所以整个以太坊系统未来规模再发展的话,可以说是全球超级计算机系统,人人都可以开发程序放在这个超级计算机运行。再说一点,这种模式的优点,现在的都是集中的云服务器,中心化的,可能有几个备份,但是一旦坏死,就不能运行,但是点对点的网络特点就是,就算几个节点下线了,或者被攻击了,有一部分在运行整个系统还是可以运行,抗风险抗错性很高。所以从最底层的定义来说,比特币解决的世界货币问题,没有能增发货币,没有能说取消或者没收你财产,直接真正存在网络上,你自己完全保管。以太坊则是,做全球的超级计算机,提供整个系统的底层,未来以太坊可能像现在电一样的底层基础资源。(后面还会学习量子链,也有可能是基础)(2)从技术上还是说点吧,上面已经说了,比特币是点对点数字货币系统,整个系统是基于UTXO的交易模型建立的,侧重点是在交易和数据结构的布局及记录。而以太坊呢,是虚拟机,完整的说法应该是智能合约虚拟机,也就是侧重按照合约的模式执行合约的虚拟机。所以呢以太坊是基于Account模型的(也有地方说EVM,就智能合约虚拟机,为什么说Account,是账户模式,以太坊是基于账户体系的)。所以呢,以太坊虽然在比特币基础学习了一些,但也创造了新的模式,为后面开发者提供了思路,同时呢后面开发应用者基本是在这两种模式下选择一种作为自己的应用模式。量子链做的事情就希望兼容两种模型,或者说打通两者,使更多应用相应的兼容。其他技术上面呢,算哈希和工作量证明上也是不同的。比特币是基于矿工计算唯一正确的哈希值,来证明工作量来获得记账打包区块权,从而获得奖励,这个用的就是工作量证明(Pow)。而以太坊希望优化这个工作,因为比特币挖矿的这种模式算力比较集中,比如专业的矿机出现,第二也比较浪费电力,浪费社会资源。提出权益证明机制(Pos),能避免一定的算力集中和资源浪费。现在以太坊才有是两种机制混合型,占比不同,以后逐步过渡到全Pos机制。                              
KeyBM  ·  2018-08-30
1196阅读  ·  12赞赏  ·   0问答

区块链笔记:主流共识算法

主流共识算法首先,贴出来各大网站我看到的一些对于面试者的要求1.熟练掌握以太坊、比特币、区块链的原理、机制;2.理解主流共识算法,包括不限于POW,POS,DPOS,PBFT,PAXOS,RAFT3.熟悉智能合约和Solidity编程优先;4.熟悉各种数据结构和算法,对密码学,安全协议和加密算法有研究;5.Hyperledge,以太坊等公开区块链项目研究或参与者什么是共识机制区块链中新的区块由谁来挖,比如比特币在全世界有那么多的矿工,那如何决定下一个区块又谁来挖,如果有人一起挖出来怎么办。所以,我们需要一种机制来保证区块链中的每一块只能由一个节点来负责写入所以,如何选出来这个矿工,就需要一种所有矿工都同意的共识机制,让平等的所有参与者按照某种秩序达成一致意见。这种机制就是共识算法。打个比方,现在有一个中心数据库,所有客户端都能来查询,每个客户端权限都是一样,但如果要对数据库进行增删改,不好意思,每次只允许一个客户端来操作,通俗讲,就是让数据库串行修改数据库。通过一个算法机制来抉择出操作的客户端。这个机制就是共识机制,所谓的共识就是在人人平等的社会里需要大家共同形成一个共识,产生一个操作者、临时决策者,代表大家来进行中心化的操作,大家按照这个共识来维持去中心化的网络世界。共识算法在区块链中的作用-----拜占庭将军问题区块链中的共识算法说到底还是分布式系统中最重要的一致性问题如何在分布式网络中保证数据一致性1.何为拜占庭将军问题拜占庭将军问题,是Leslie Lamport 1982年提出用来解释一致性问题的一个虚构模型。这个模型大概是这样的拜占庭帝国想要进攻一个强大的敌人,为此派出了10支军队去包围这个敌人。这个敌人虽不比拜占庭帝国,但也足以抵御5支常规拜占庭军队的同时袭击。这10支军队在分开的包围状态下同时攻击。他们任一支军队单独进攻都毫无胜算,除非有至少6支军队(一半以上)同时袭击才能攻下敌国。他们分散在敌国的四周,依靠通信兵骑马相互通信来协商进攻意向及进攻时间。困扰这些将军的问题是,他们不确定他们中是否有叛徒,叛徒可能擅自变更进攻意向或者进攻时间。在这种状态下,拜占庭将军们才能保证有多于6支军队在同一时间一起发起进攻,从而赢取战斗?Leslie Lamport 证明,当叛变者不超过1/3时,存在有效的算法,不论叛变者如何折腾,忠诚的将军们总能达成一致的结果。如果叛变者过多,则无法保证一定能达到一致性。2.拜占庭将军问题的理解拜占庭假设是对现实世界的模型化,由于硬件错误、网络阻塞或断开以及遭到恶意攻击,计算机和网络可能出现不可预料的行为。拜占庭容错协议必须处理这些失效,并且这些协议还要满足所要解决的问题要求的规范。这些算法通常以其弹性t作为特征,t表示算法可以应付的错误进程数。很多经典算法问题只有在n ≥ 3t+1时才有解,如拜占庭将军问题,其中n是系统中进程的总数。拜占庭容错能够容纳将近1/3的错误节点误差,IBM创建的Hyperledger就是使用了该算法作为共识算法。具体共识算法介绍1.拜占庭共识算法系列PBFT/DBFT机制:DBFT机制:是由权益来选出记账人,然后记账人之间通过拜占庭容错算法来达成共识,这种方式的优点是:(1)专业化的记账人;(2)可以容忍任何类型的错误;(3)记账由多人协同完成,每一个区块都有最终性,不会分叉;(4)算法的可靠性有严格的数学证明;缺点:(1)当有1/3或以上记账人停止工作后,系统将无法提供服务(2)当有1/3或以上记账人联合作恶,且其他所有的记账人被恰好分割为两个网络孤岛时,恶意记账人可以使系统出现分叉,但是会留下密码学证据;2.工作量证明POW工作量证明,Proof of Work,通过计算来猜测一个数值(nonce),得以解决规定的 hash 问题(来源于 hashcash)。保证在一段时间内,系统中只能出现少数合法提案。同时,这些少量的合法提案会在网络中进行广播,收到的用户进行验证后会基于它认为的最长链上继续难题的计算。因此,系统中可能出现链的分叉(Fork),但最终会有一条链成为最长的链。3.权益证明POS权益证明,Proof of Stake,2013 年被提出,最早在 Peercoin 系统中被实现,类似现实生活中的股东机制,拥有股份越多的人越容易获取记账权。典型的过程是通过保证金(代币、资产、名声等具备价值属性的物品即可)来对赌一个合法的块成为新的区块,收益为抵押资本的利息和交易服务费。提供证明的保证金(例如通过转账货币记录)越多,则获得记账权的概率就越大。合法记账者可以获得收益。PoS 是试图解决在 PoW 中大量资源被浪费的缺点。恶意参与者将存在保证金被罚没的风险,即损失经济利益。一般的,对于 PoS 来说,需要掌握超过全网 的资源,才有可能左右最终的结果。这个也很容易理解,三个人投票,前两人分别支持一方,这时候,第三方的投票将决定最终结果。4.授权股权证明机制DPOSPoS 的改进算法,DPOS与POS原理相似。与POS的主要区别在于节点选举若干代理,由代理人验证和记账。PoW机制和PoS机制虽然都能有效地解决记账行为的一致性共识问题,但是现有的比特币PoW机制纯粹依赖算力,导致专业从事挖矿的矿工群体似乎已和比特币社区完全分隔,某些矿池的巨大算力俨然成为另一个中心,这与比特币的去中心化思想相冲突。PoS机制虽然考虑到了PoW的不足,但依据权益结余来选择,会导致首富账户的权力更大,有可能支配记账权。股份授权证明机制( Delegated Proof of Stake,DPoS)的出现正是基于解决PoW机制和PoS机制的这类不足。目前主流区块链分别用的是什么共识算法1.PoW共识算法代表:比特币&莱特币&以太坊比特币采用的是PoW(Proof of Work),工作量证明,通过计算来猜测一个数值(nonce),得以解决规定的 hash 问题。挖矿的过程就是找到x使得以下等式成立:SHA256(SHA256(version + prev_hash + merkle_root + ntime + nbits + x )) < TARGET上式的x的范围是0~2^32, TARGET可以根据当前难度求出的。由于hash的特性,找这样一个x只能暴力搜索。PoW共识算法的核心是所有节点通过暴力查找x,使得上面的等式成立。谁先找到谁就或者这一区块的写入权,并获得奖励,因此pow共识机制对所有节点都公平,谁的算力强谁就更有机会更高概率获得写入权。2.PoS机制代表:Peercoin & Nxt点点币(Peercoin )的权益证明机制结合了随机化与币龄的概念,未使用至少30天的币可以参与竞争下一区块,越久和越大的币集有更大的可能去签名下一区块。然而,一旦币的权益被用于签名一个区块,则币龄将清为零,这样必须等待至少30日才能签署另区块。同时,为防止非常老或非常大的权益控制区块链,寻找下一区块的最大概率在90天后达到最大值,这一过程保护了网络,并随着时间逐渐生成新的币而无需消耗大量的计算能力。点点币的开发者声称这将使得恶意攻击变得困难,因为没有中心化的挖矿池需求,而且购买半数以上的币的开销似乎超过获得51%的工作量证明的哈希计算能力。权益证明必须采用某种方法定义任意区块链中的下一合法区块,依据账户结余来选择将导致中心化,例如单个首富成员可能会拥有长久的优势。为此,人们还设计了其他不同的方法来选择下一合法区块。NXT币采用随机方法预测下一合法区块,使用公式查找与权益大小结合的最小哈希值。由于权益公开,每个节点都可以合理的准确度预计哪个账户有权建立区块。3.DPoS共识算法代表:Bitshare & EOS比特股( Bitshare)是一类采用DPoS机制的密码货币,它期望通过引入一个技术民主层来减少中心化的负面影响。比特股引入了见证人这个概念,见证人可以生成区块,每一个持有比特股的人都可以投票选举见证人。得到总同意票数中的前N个(N通常定义为101)候选者可以当选为见证人,当选见证人的个数(N)需满足:至少一半的参与投票者相信N已经充分地去中心化。见证人的候选名单每个维护周期(1天)更新一次。见证人然后随机排列,每个见证人按序有2秒的权限时间生成区块,若见证人在给定的时间片不能生成区块,区块生成权限交给下一个时间片对应的见证人。DPoS的这种设计使得区块的生成更为快速,也更加节能。DPoS充分利用了持股人的投票,以公平民主的方式达成共识,他们投票选出的N个见证人,可以视为N个矿池,而这N个矿池彼此的权利是完全相等的。持股人可以随时通过投票更换这些见证人(矿池),只要他们提供的算力不稳定,计算机宕机,或者试图利用手中的权力作恶。比特股还设计了另外一类竞选,代表竞选。选出的代表拥有提出改变网络参数的特权,包括交易费用、区块大小、见证人费用和区块区间。若大多数代表同意所提出的改变,持股人有两周的审查期,这期间可以罢免代表并废止所提出的改变。这一设计确保代表技术上没有直接修改参数的权利以及所有的网络参数的改变最终需得到持股人的同意。
KeyBM  ·  2018-09-05
1125阅读  ·  12赞赏  ·   0问答

solidity实现 erc721合约

# Solidity-Vampire-ERC721使用erc721 配合erc20 的宠物游戏实现自己的ERC721宠物你想拥有一个独一无二的宠物吗以太坊 erc721 可以满足你,每一个个体都是独一无二的存在,举个例子:例如人民币(erc20) 一张坏了可以用另一张支付,这是可替换的。但是erc721可以类比成什么呢,世界上没有完全相同的树叶如对erc721 和 erc20 概念不是很理解的同志请自行查阅资料,哈哈,不过多解释本文章采用 erc721 + erc20 的方式 实现,erc20 代币 用作合约之中的流通货币,例如 宠物战斗,宠物繁殖,宠物竞拍的手续费,也可以直接采用erc20代币直接购买宠物!本文引入了erc20 ,和 erc721 的接口 并对erc721 进行实现,而只调用部分erc20方法。接下来就带你一步一步实现自己的宠物先大概构想一个宠物合约应有的功能,最基本的应该是繁殖,但不能无限繁殖,应先规定多久繁殖一次,本合约采用的是每个用户可获得一个宠物,随后获得宠物需要进食,然后有概率获得宠物,获得的宠物等级会在原等级相加,但是稀有度就看自己的运气了哈哈,一般来说等级越高,稀有度越稀有的宠物也就越珍贵。创建宠物时会默认为宠物生成一个用户名,用户可以根据自己的喜好来更改这个用户名,但是需要支付很少一部分的手续费用随后设想宠物的战斗功能,宠物有战斗力性质的存在,但是规定战斗胜利的基准是什么呢,是运气,没错就是运气,合约采用随机几率的方式来决定战斗输赢,赢了的一方将获得代币奖励,和战斗力增加,战斗也不可能无休止的进行,那怎么办呢,咱们接着为他加上冷却时间吧。输了也不可能一点惩罚没有,我们采用的是降低战斗力的方式。想让宠物战斗获取代币 你只需要支付一定量的代币(手续费),什么又是代币,没错有代币你就可以为所欲为!然而这个可以让用户为所欲为的代币从哪里来呢? 这点很重要根据自己需要的场景来选择,如果你希望自己的代币 还有宠物 仅作为娱乐性质,那就可以 让用户每天签到获得代币,现在的合约里实现是前两周可以通过签到获得,后边需要再获得代币就需要联系 发币项目方了。可以通过这种方式让用户一直获得代币。然而如果你准备商用签到的方式可以保留,但是在此获取代币就需要用 人民币来购买喽,发币 上交易所 割韭菜 哈哈楼主还是不推荐这么干的。要让宠物真正的流通起来 除了用户和用户的交易,最好的办法是什么,当然是拍卖,用户设定最低出价,拍卖时间由系统规定,然后你就可以坐等收币了,等竞拍完成,项目方会把你获得的代币,还有竞拍者获得的宠物双双交还。接下来我们来具体实现它首先定义一下 宠物要有的东西:名字 , DNA, 等级, 父亲是谁,战斗力,稀有度以及创建时间此图包含了竞拍的结构体,留作接下来 实现竞拍所用,具体的东西有:参与人,参与人的金额, 初始金额, 是否完成竞拍宠物发放, 最后就是竞拍时间一个产品没有客户端是做不起来的,然后客户端怎么知道创建了一个宠物或者 你给宠物重新定义了一个名字呢solidity中有个东西叫做监听 event。试想一下咱们要返回给客户端的时候,创建了一个宠物,重命名了一个宠物,战斗获胜的宠物,还有竞拍的时候看一下合约中具体要用到的变量,战斗的冷却时间,创建新僵尸的各种时间,还有各项费用。因为区块链的不可更改特性,很多时候一个值都不能固定,例如签到获得的币,交易的手续费,这些都应该根据具体的现场场景来设置。所以我们实现了具体的方法然后咱们要实现设置宠物的稀有度,dna等的私有方法,来看一下具体实现然后来看一下创建宠物的具体方法战斗的具体实现:竞拍要分为 发起竞拍,竞拍中,竞拍结束的多步操作,咱们逐一实现最后是针对erc721合约的具体实现,一个宠物本质就是erc721 (非同质货币)实现起来到这里就差不多结束了,可以根据自己的需求,进行功能的拓展,接下来会对合约进行逐步更新,修正bug等。是不是已经心动了,下面是我的github实现地址, 欢迎fork,共同学习https://github.com/skyhuihui/Solidity-Vampire-ERC721.git如果您想支持我 可以像我的地址上转一些以太币 0x2207358972e37f663a5480dbaa09715e8b0fc4ff,什么你只有新潮的eos 没有以太币,放心放心,eos地址我也有 eosskyhuihui算了开玩笑的了,哈哈, 您的转发就是对我最大的支持。
skyhuihui  ·  2018-08-18
1971阅读  ·  10赞赏  ·   0问答

感谢您的提问,问题被社区永久收入以便新人查看。一定要记得采纳最佳答案哦!加油!

感谢您的善举,每一次解答会成为新人的灯塔,回答被采纳后获得20算力和相应的LK币奖励

您将赞赏给对方2LK币的奖励哦!感谢您的赞赏!

您将赞赏给对方2LK币的奖励哦!感谢您的赞赏!