智能合约-建立标准币

truffle Boxes功能,react-box样板,已经整合了create-react-app,可以直接开发react web,省下项目设置的时间。

不再用truffle init

再终端,mkdir 新项目,切换到项目文件夹

执行

truffle unbox react-box

网路不好多试几次

Commands:

  Compile:              truffle compile   //编译命令

  Migrate:              truffle migrate //部署

  Test contracts:       truffle test //测试

  Test dapp:            npm test

  Run dev server:       npm run start //打开web端

  Build for production: npm run build  //发布的时候通过这个命令

运行web端看下 npm run start

Failed to compile.

Error in ./src/App.js Module not found: ../build/contracts/SimpleStorage.json in /Users/zhangheng/Desktop/0921demo/demo2/src @ ./src/App.js 14:21-69

报错,!!!!!!

原因是没有编译,部署。

atom打开项目目录

contracts  合约文件

migrations 部署文件

node_modules 相关的依赖包

src  主要用来写react,

App.js 可以调用合约的部署的相关的方法,和部署到区块              链的合约互动

package.json   node_modules相关的依赖包

开发前准备

1、打卡终端,启动testrpc,通过testrpc模拟以太坊区块链测试环境

2、创建的代币如果想要能够通过以太币钱包来进行转账和收账,必须兼容于以太坊的ERC20标准,ERC20定义了支持钱包所必须的合约界面。

3、安装OpenZeppeLin来简化加密钱包开发的过程。OpenZeppeLin是一套能够给我们方便提供编写加密合约的函数库,同时也提供了兼容ERC20的智能合约。

查看项目package.json 中的dependencies只有3个依赖库

控制台执行 npm install zeppelin-solidity然后会发现package.json 中的dependencies会多出一个依赖库并且node_modules文件夹会多出一个

zenppelin-solidity文件夹

contracts  合约文件夹

token   //写代码是会调用到这个标准的合约

在项目合约文件夹下新建合约文件写入以下代码(文件名自取)

pragma solidity ^0.4.2;
import “zeppelin-solidity/contracts/token/StandardToken.sol”;
//这时区块链上就多了一个币种zhangheng币这是一个比较夯实的合约了
contract ZhanghengCoin is StandardToken {
string public name = “ZhanghengCoin”; //全名
string public symbol = “ZTC”; //简写
uint8 public decimals = 4 ; //最小分割单位0.0001个可以找零,如果是8就是0.00000001个
uint256 public INITIAL_SUPPLY = 888888; //初始化数字货币的数量
function ZhanghengCoin() {
totalSupply = INITIAL_SUPPLY; //初始化的货币数量,totalSupply从父类继承
balances[msg.sender] = INITIAL_SUPPLY;

}

}

在部署合约文件夹下新建部署合约文件

var ZhanghengCoin = artifacts.require(“./ZhanghengCoin.sol”);

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

部署,编译,验证,世界上新的币种就要诞生了

.编译,打开终端,在当前项目目录下输入命令

truffle compile      项目目录下会多出一个build文件夹

在终端当前项目目录下执行truffle migrate开始部署(别忘了配置文件配置本地服务)

验证几个方法是否可用

控制台 truffle console

let contract //声明变量

ZhanghengCoin.deployed().then(instance=>contract=instance) //实例化合约并存储

contract.address //查看部署的合约地址,当前部署的合约的钱包的地址,一个钱包可以部署多个合约地址,每个合约都有一个地址。

contract.balanceOf(web3.eth.coinbase) //查看钱包的余额

contract.balanceOf(web3.eth.accounts[1]) // 查看下标为1的钱包余额

contract.name.call()  // 查看属性

contract.transfer(web3.eth.accounts[5],60000)  //向测试钱包转账

contract.balanceOf(web3.eth.coinbase) //查看余额变了

控制台切换项目根目录执行  npm run start //打开网页查看

代码在app.js中

react与合约互动开始了

https://gist.github.com/anonymous/e6cf9aa2e063641d1dfa4b0d22bb6896

智能合约-建立标准代币

终端输入testrpc启动以太坊开发环境,会生成10个钱包临时的地址和10个对应的钱包秘钥,部署合约需要花费以太币,每个钱包有10个以太币(不要关闭终端)

新建代币合约

truffle create contract EncryptedToken 命令创建EncryptedToken.sol合约。写入以下代码

pragma solidity ^0.4.4;

contract EncryptedToken {
uint256 INITIAL_SUPPLY = 666666; //代币初始值
mapping(address => uint256) balanses;
function EncryptedToken() {
// constructor
balanses[msg.sender] = INITIAL_SUPPLY;
}
//转账到一个指定的地址,钱包地址,转账数量
function transfer(address _to,uint256 _amount) {
assert(balanses[msg.sender] >= _amount);
balanses[msg.sender] -= _amount;
balanses[_to] += _amount;
}

//查看指定地址的余额
function blanxeOf(address _owner) constant returns (uint256) {
return balanses[_owner];
}
}

编译

truffle compile

部署

truffle migrate

与合约互动

truffle console

let contract

实例化合约并存储

EncryptedToken.deployed().then(instance=>contract=instance)

测试服务提供了10个钱包地址查看第一个地址

web3.eth.coinbase

或者

web3.eth.accounts[0]

默认币存在第一个钱包里面

查看钱包余额

contract.blanxeOf(web3.eth.accounts[0])

会输出

BigNumber { s: 1, e: 5, c: [ 666666 ] }  //s代表开始,e:代表结束加起来是这条数据的长度

从当前的合约中转账到第一钱包//默认的第一个钱包账号,部署到线上后哪个钱包地址部署的就是哪一个地址

contract.transfer(web3.eth.accounts[1],66666666)  //大于余额会发生异常,

contract.transfer(web3.eth.accounts[1],60000)

然后查看第这两个钱包的余额变动

contract.blanxeOf(web3.eth.accounts[0])

contract.blanxeOf(web3.eth.accounts[1])

一个简单的加密合约代码

备注:编译时,要将build文件夹删除,其次在部署合约时,一定要添加–reset,否则修改后的合约没法部署成功。

漏洞:验证钱包的地址是否合法

 

 

 

 

【Ethereum】以太坊ERC20 Token标准完整说明

什么是ERC20 token

市面上出现了大量的用ETH做的代币,他们都遵守REC20协议,那么我们需要知道什么是REC20协议。

概述

token代表数字资产,具有价值,但是并不是都符合特定的规范。

基于ERC20的货币更容易互换,并且能够在Dapps上相同的工作。

新的标准可以让token更兼容,允许其他功能,包括投票标记化。操作更像一个投票操作

Token的持有人可以完全控制资产,遵守ERC20的token可以跟踪任何人在任何时间拥有多少token.基于eth合约的子货币,所以容易实施。只能自己去转让。

标准化非常有利,也就意味着这些资产可以用于不同的平台和项目,否则只能用在特定的场合。

ERC20 Token标准(Github)

序言

EIP: 20 
Title: ERC-20 Token Standard 
Author: Fabian Vogelsteller fabian@ethereum.org, Vitalik Buterin vitalik.buterin@ethereum.org 
Type: Standard 
Category: ERC 
Status: Accepted 
Created: 2015-11-19

总结

token的接口标准

抽象

以下标准允许在智能合约中实施标记的标记API。 该标准提供了转移token的基本功能,并允许token被批准,以便他们可以由另一个在线第三方使用。

动机

标准接口可以让Ethereum上的任何令牌被其他应用程序重新使用:从钱包到分散式交换。

规则

Token

方法

注意:调用者必须处理返回falsereturns (bool success).调用者绝对不能假设返回false的情况不存在。

name

返回这个令牌的名字,比如"MyToken".

可选 – 这种方法可以用来提高可用性,但接口和其他契约不能指望这些值存在。

function name() constant returns (string name)
  • 1

symbol

返回令牌的符号,比如HIX.

可选 – 这种方法可以用来提高可用性,但接口和其他契约不能指望这些值存在。

function symbol() constant returns (string symbol)
  • 1

decimals

返回token使用的小数点后几位, 比如 8,表示分配token数量为100000000

可选 – 这种方法可以用来提高可用性,但接口和其他契约不能指望这些值存在。

function decimals() constant returns (uint8 decimals)
  • 1

totalSupply

返回token的总供应量。

function totalSupply() constant returns (uint256 totalSupply)
  • 1

balanceOf

返回地址是_owner的账户的账户余额。

function balanceOf(address _owner) constant returns (uint256 balance)
  • 1

transfer

转移_value的token数量到的地址_to,并且必须触发Transfer事件。 如果_from帐户余额没有足够的令牌来支出,该函数应该被throw

创建新令牌的令牌合同应该在创建令牌时将_from地址设置为0x0触发传输事件。

注意 0值的传输必须被视为正常传输并触发传输事件。

function transfer(address _to, uint256 _value) returns (bool success)
  • 1

transferFrom

从地址_from发送数量为_value的token到地址_to,必须触发Transfer事件。

transferFrom方法用于提取工作流,允许合同代您转移token。这可以用于例如允许合约代您转让代币和/或以子货币收取费用。除了_from帐户已经通过某种机制故意地授权消息的发送者之外,该函数**应该**throw。

注意 0值的传输必须被视为正常传输并触发传输事件。

function transferFrom(address _from, address _to, uint256 _value) returns (bool success)
  • 1

approve

允许_spender多次取回您的帐户,最高达_value金额。 如果再次调用此函数,它将以_value覆盖当前的余量。

注意:为了阻止向量攻击,客户端需要确认以这样的方式创建用户接口,即将它们设置为0,然后将其设置为同一个花费者的另一个值。虽然合同本身不应该强制执行,允许向后兼容以前部署的合同兼容性

function approve(address _spender, uint256 _value) returns (bool success)
  • 1

allowance

返回_spender仍然被允许从_owner提取的金额。

function allowance(address _owner, address _spender) constant returns (uint256 remaining)
  • 1

Events

Transfer

当token被转移(包括0值),必须被触发。

event Transfer(address indexed _from, address indexed _to, uint256 _value)
  • 1

Approval

当任何成功调用approve(address _spender, uint256 _value)后,必须被触发。

event Approval(address indexed _owner, address indexed _spender, uint256 _value)
  • 1

实施

在Ethereum网络上部署了大量符合ERC20标准的令牌。 具有不同权衡的各种团队已经编写了不同的实施方案:从节省gas到提高安全性。

示例实现可在

在调用之前添加力0的实施“批准”了

ERC20 Token标准接口

以下是一个接口合同,声明所需的功能和事件以符合ERC20标准:

// https://github.com/ethereum/EIPs/issues/20
  contract ERC20 {
      function totalSupply() constant returns (uint totalSupply);
      function balanceOf(address _owner) constant returns (uint balance);
      function transfer(address _to, uint _value) returns (bool success);
      function transferFrom(address _from, address _to, uint _value) returns (bool success);
      function approve(address _spender, uint _value) returns (bool success);
      function allowance(address _owner, address _spender) constant returns (uint remaining);
      event Transfer(address indexed _from, address indexed _to, uint _value);
      event Approval(address indexed _owner, address indexed _spender, uint _value);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

大部分Ethereum主要标记符合ERC20标准。

一些令牌包括描述令牌合同的进一步信息:

string public constant name = "Token Name";
string public constant symbol = "SYM";
uint8 public constant decimals = 18;  // 大部分都是18
  • 1
  • 2
  • 3

如何工作?

以下是令牌合约的一个片段,用于演示令牌合约如何维护Ethereum帐户的令牌余额

contract TokenContractFragment {

     // Balances 保存地址的余额
     mapping(address => uint256) balances;

     // 帐户的所有者批准将金额转入另一个帐户
     mapping(address => mapping (address => uint256)) allowed;

      // 特定帐户的余额是多少?
      function balanceOf(address _owner) constant returns (uint256 balance) {
          return balances[_owner]; //从数组中取值
      }

      // 将余额从所有者帐户转移到另一个帐户
      function transfer(address _to, uint256 _amount) returns (bool success) {
          //判断条件 发送者余额>=要发送的值  发送的值>0  接收者余额+发送的值>接收者的余额
          if (balances[msg.sender] >= _amount 
              && _amount > 0
              && balances[_to] + _amount > balances[_to]) {
              balances[msg.sender] -= _amount;   //发送者的余额减少
              balances[_to] += _amount;         //接收者的余额增加
              return true;
         } else {
              return false;
          }
      }

      // 发送 _value 数量的token从地址 _from 到 地址 _to
      // transferFrom方法用于提取工作流程,允许合同以您的名义发送令牌,例如“存入”到合同地址和/或以子货币收取费用; 该命令应该失败,除非_from帐户通过某种机制故意地授权消息的发送者; 我们提出这些标准化的API来批准:
      function transferFrom(
          address _from,
          address _to,
          uint256 _amount
     ) returns (bool success) {
          //和上面一样的校验规则
          if (balances[_from] >= _amount
              && allowed[_from][msg.sender] >= _amount
              && _amount > 0
              && balances[_to] + _amount > balances[_to]) {
              balances[_from] -= _amount;
              allowed[_from][msg.sender] -= _amount; //减少发送者的批准量
              balances[_to] += _amount;
              return true;
         } else {
             return false;
          }
      }

      // 允许_spender多次退出您的帐户,直到_value金额。 如果再次调用此函数,它将以_value覆盖当前的余量。
      function approve(address _spender, uint256 _amount) returns (bool success) {
          allowed[msg.sender][_spender] = _amount; //覆盖当前余量
          return true;
      }
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

token余额

假设token合约内有两个持有者

  • 0x1111111111111111111111111111111111111111有100个单位
  • 0x2222222222222222222222222222222222222222有200个单位

那么这个合约的balances结构就会存储下面的内容

balances[0x1111111111111111111111111111111111111111] = 100
balances[0x2222222222222222222222222222222222222222] = 200
  • 1
  • 2

那么,balanceOf(...)就会返回下面的结果

tokenContract.balanceOf(0x1111111111111111111111111111111111111111) 将会返回 100
tokenContract.balanceOf(0x2222222222222222222222222222222222222222) 将会返回 200
  • 1
  • 2

转移token的余额

如果0x1111111111111111111111111111111111111111想要转移10个单位给0x2222222222222222222222222222222222222222,那么0x1111111111111111111111111111111111111111会执行下面的函数

tokenContract.transfer(0x2222222222222222222222222222222222222222, 10)
  • 1

token合约的transfer(...)方法将会改变balances结构中的信息

balances[0x1111111111111111111111111111111111111111] = 90
balances[0x2222222222222222222222222222222222222222] = 210
  • 1
  • 2

balanceOf(...)调用就会返回下面的信息

tokenContract.balanceOf(0x1111111111111111111111111111111111111111) 将会返回 90
tokenContract.balanceOf(0x2222222222222222222222222222222222222222) 将会返回 210
  • 1
  • 2

从token余额批准和转移

如果0x1111111111111111111111111111111111111111想要批准0x2222222222222222222222222222222222222222传输一些token到0x2222222222222222222222222222222222222222,那么0x1111111111111111111111111111111111111111会执行下面的函数

tokenContract.approve(0x2222222222222222222222222222222222222222, 30)
  • 1

然后allowed(这里官方文档写的是approve,很明显是错的)结构就会存储下面的内容

tokenContract.allowed[0x1111111111111111111111111111111111111111][0x2222222222222222222222222222222222222222] = 30
  • 1

如果0x2222222222222222222222222222222222222222想要晚点转移token从0x1111111111111111111111111111111111111111到他自己,0x2222222222222222222222222222222222222222将要执行transferFrom(...)函数

tokenContract.transferFrom(0x1111111111111111111111111111111111111111, 20)
  • 1

balances的信息就会变成下面的

tokenContract.balances[0x1111111111111111111111111111111111111111] = 70
tokenContract.balances[0x2222222222222222222222222222222222222222] = 230
  • 1
  • 2

然后allowed就会变成下面的内容

tokenContract.allowed[0x1111111111111111111111111111111111111111][0x2222222222222222222222222222222222222222] = 10
  • 1

0x2222222222222222222222222222222222222222仍然可以从0x1111111111111111111111111111111111111111转移10个单位。

tokenContract.balanceOf(0x1111111111111111111111111111111111111111) will return 70
tokenContract.balanceOf(0x2222222222222222222222222222222222222222) will return 230
  • 1
  • 2

简单修复的token合约

以下是一个样本令牌合同,固定供应量为1000000单位,最初分配给合同所有者:

pragma solidity ^0.4.8;

  // ----------------------------------------------------------------------------------------------
  // Sample fixed supply token contract
  // Enjoy. (c) BokkyPooBah 2017. The MIT Licence.
  // ----------------------------------------------------------------------------------------------

   // ERC Token Standard #20 Interface
  // https://github.com/ethereum/EIPs/issues/20
  contract ERC20Interface {
      // 获取总的支持量
      function totalSupply() constant returns (uint256 totalSupply);

      // 获取其他地址的余额
      function balanceOf(address _owner) constant returns (uint256 balance);

      // 向其他地址发送token
      function transfer(address _to, uint256 _value) returns (bool success);

      // 从一个地址想另一个地址发送余额
      function transferFrom(address _from, address _to, uint256 _value) returns (bool success);

      //允许_spender从你的账户转出_value的余额,调用多次会覆盖可用量。某些DEX功能需要此功能
      function approve(address _spender, uint256 _value) returns (bool success);

      // 返回_spender仍然允许从_owner退出的余额数量
      function allowance(address _owner, address _spender) constant returns (uint256 remaining);

      // token转移完成后出发
      event Transfer(address indexed _from, address indexed _to, uint256 _value);

      // approve(address _spender, uint256 _value)调用后触发
      event Approval(address indexed _owner, address indexed _spender, uint256 _value);
  }

   //继承接口后的实例
   contract FixedSupplyToken is ERC20Interface {
      string public constant symbol = "FIXED"; //单位
      string public constant name = "Example Fixed Supply Token"; //名称
      uint8 public constant decimals = 18; //小数点后的位数
      uint256 _totalSupply = 1000000; //发行总量

      // 智能合约的所有者
      address public owner;

      // 每个账户的余额
      mapping(address => uint256) balances;

      // 帐户的所有者批准将金额转入另一个帐户。从上面的说明我们可以得知allowed[被转移的账户][转移钱的账户]
      mapping(address => mapping (address => uint256)) allowed;

      // 只能通过智能合约的所有者才能调用的方法
      modifier onlyOwner() {
          if (msg.sender != owner) {
              throw;
          }
          _;
      }

      // 构造函数
      function FixedSupplyToken() {
          owner = msg.sender;
          balances[owner] = _totalSupply;
      }

      function totalSupply() constant returns (uint256 totalSupply) {
          totalSupply = _totalSupply;
      }

      // 特定账户的余额
      function balanceOf(address _owner) constant returns (uint256 balance) {
          return balances[_owner];
      }

      // 转移余额到其他账户
      function transfer(address _to, uint256 _amount) returns (bool success) {
          if (balances[msg.sender] >= _amount 
              && _amount > 0
              && balances[_to] + _amount > balances[_to]) {
              balances[msg.sender] -= _amount;
              balances[_to] += _amount;
              Transfer(msg.sender, _to, _amount);
              return true;
          } else {
              return false;
          }
      }

      //从一个账户转移到另一个账户,前提是需要有允许转移的余额
      function transferFrom(
          address _from,
          address _to,
          uint256 _amount
      ) returns (bool success) {
          if (balances[_from] >= _amount
              && allowed[_from][msg.sender] >= _amount
              && _amount > 0
              && balances[_to] + _amount > balances[_to]) {
              balances[_from] -= _amount;
              allowed[_from][msg.sender] -= _amount;
              balances[_to] += _amount;
              Transfer(_from, _to, _amount);
              return true;
          } else {
              return false;
          }
      }

      //允许账户从当前用户转移余额到那个账户,多次调用会覆盖
      function approve(address _spender, uint256 _amount) returns (bool success) {
          allowed[msg.sender][_spender] = _amount;
          Approval(msg.sender, _spender, _amount);
          return true;
      }

      //返回被允许转移的余额数量
      function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
          return allowed[_owner][_spender];
      }
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120

注意的是,最后的例子中allowed限定的第二维的参数是调用者的转移数量,而开始的例子是接收者的数量。

参考资料

以太坊私有链开发

开源工具和语言

1、berwMacOS包管理器 https://brew.sh

/usr/bin/ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)”

2、install Go compiler

brew install go

3、geth运行以太坊节点,下载 https://github.com/ethereum/go-ethereum/archive/v1.5.9.tar.gz

解压cd go-ethereum-1.5.9

make geth

4、Solidity以太坊智能合约语言

brew install solidity

时间有点长耐心等待…………….

http://blog.csdn.net/Sico2Sico/article/details/71082130

回到终端 执行

export HOMEBREW_GITHUB_API_TOKEN="bd021897f6589a77276a08f6919f92a888a2b56a"

 

 

以太坊智能合约编写

开发工具 Atom

  1. 首页安装nodjs然后在控制台输入

    npm install -g ethereumjs-testrpc truffle

  2. 终端输入testrpc启动以太坊开发环境,会生成10个钱包临时的地址和10个对应的钱包秘钥,部署合约需要花费以太币,每个钱包有10个以太币(不要关闭终端)
  3. 打开新的终端,创建项目,cd Desktop/ 切换到桌面,mkdir ContractDemo
  4. cd ContractDemo;然后执行truffle init创建新项目。ls查看文件目录
  5. 终端输入 atom ./ 用atom工具打开
  6. conteacts/xxx.sol  默认合约代码                               migrations/1_initial_migration.js 部署合约时监听合约的变化,2_deploy_contracts.js部署合约时往里边写部署合约的代码。test文件夹下的代码写测试用例
  7. 在contracts下新建一个HelloWorld.sol,输入以下代码

pragma solidity ^0.4.17; //编译版本的声明 ^代表兼容 0.4.17~0.4.9,不能超过0.5
//contract 相当于声明了一个类class HelloWorld extends contract 创建了一个合约
contract HelloWorld {
function HelloWorld() {
//构造函数。与类名相同
}
function sayHello() returns (string) {
//方法里的参数需要有类型。返回的参数也要有类型
return (“Hello World”);
}

}

 

8.编译,打开终端,在当前项目目录下输入命令

truffle compile      项目目录下会多出一个build文件夹

编译完成以后才能部署

9、在终端当前项目目录下执行truffle migrate开始部署

Error: No network specified. Cannot determine current network.报错了!!!!!,原因是

导致上面异常的原因为是因为truffle.js里面未配置链接合约发布的环境地址,找到对应的truffle.js文件,修改代码为类似如下配置即可解决问题:

 

module.exports = {
    networks: {
        development: {
            host: "localhost",
            port: 8545,
            network_id: "*" // 匹配任何network id
         }
    }
};


另一个监听控制台输出的:

Using network ‘development’ 代表的是开发环境

Transaction://部署合约的地址

Gas usage://部署合约花费的燃料费/手续费

Block Time://部署合约的时间

与合约互动

truffle 提供命令行工具,执行truffle console命令后,可用js与刚才部署的合约互动

let contract  //声明一个变量

HelloWorld.deployed().then(instance=>contract=instance)//

       instance合约实例contract刚才声明的变量 instance 把这个合约存储起来

执行

contract.sayHello.call()控制台输出 

‘Hello World’

call()方法代表只读,简单的读取数据,不会消耗gas,

直接调用sayHello()会打印出交易的过程来,写入会消耗gas

写代码时加关键字constant声明,标示调用这个方法不会改变区块链的状态。如此一来,透过truffle-contract来调用此方法时,会自动选用call来呼叫,也不粗要额外提供gas

修改同一个文件编译后部署需要加参数  –reset

 

区块链运行原理demo,挖矿算法

地址:www.blockchaindemo.io

  • 终端演示 macOS 10.12
  • 先安装 npm ,node
  1. npm install blockchain-cli -g
  2. 输入 blockchain打开一个终端
  3. bc ,blockchaim简写,(看到了第一个创世区块)

    ┌─────────────────────────────────────────┐

                🏆  Genesis Block            

    ├────────────────────┬────────────────────┤

    │ ⏮  Previous Hash   │ 0                 

    ├────────────────────┼────────────────────┤

    │ 📅  Timestamp       │ Thu, 27 Jul 2017  

                        │ 02:30:00 GMT      

    ├────────────────────┼────────────────────┤

    │ 📄  Data            │ Welcome to        

                        │ Blockchain CLI!   

    ├────────────────────┼────────────────────┤

    │ 📛  Hash            │ 0000018035a828da0… │

    ├────────────────────┼────────────────────┤

    │ 🔨  Nonce           │ 56551             

    └────────────────────┴────────────────────┘

    Previous Hash ;上一个区块的哈希值                    Timestamp :挖矿的时间戳                                     Data:当前的交易数据                                               Hash:当前的哈希值                                                      Nonce:满足当前的哈希值某个难度的前导0随机数  (挖矿的时候找这个Nonce值。找到了成功)

  4. 挖矿 输入 命令 mine  zh17769225922 (参数随便写的)

挖矿成功以后产生新的区块

Block #1 第1号区块,创世区块时第0号

5. 输入 bc查看所有区块

6.可以继续挖,mine  你好   (数据中文也可以)

Hash是怎么计算的?

Hash值是一个十六进制固定长度为64的唯一标示

Hash值是由index,previous block hash ,timestamp,bloc data,和nonce作为数据计算的

CryptoJS.SHA256(index+previousHash+timestamp+data+nonce)

4个前导0是有效散列的最低要求。所需的前导0的数量称为难度

工作量证明系统Proof-of-Work system

下面的方法验证hash难度是否有效。

function isValidHashDifficulty(hash,difficulty){

for(var i=0,b=hash.length;i<b;i++){

if(hash[i] !==’0′){

break;

}

}

return i>=difficulty;

}

什么是nonce?

nonce是一个用来找到满足条件的hash值得数字。

let nonce = 0;

let hash;

let input;

while(!isValidHashDifficulty(hash)){

nonce = nonce + 1;

input = index + previousHash + timestamp + data +nonce;

hash = CryptoJS.SHA256(input);

Bitcoin Core钱包

 

1、下载地址:https://bitcoin.org/zh_CN/choose-your-wallet(非开发人员就别玩了,直接看下一个)

2、无需下载直接使用:https://www.myetherwallet.com

2、1 英文不好的切换一下了,如果果六级了可以跳过

输入密码(不要忘记,千万别忘记

点击生成钱包

点击下载keystore File(此文件一定要保存好,丢了钱包就找不回来了)

然后点击 I understand. Continue

保存你的私钥,可以打印纸钱包(前提是你的电脑连接了打印机)

点击 -保存你的地址

2.2 选择 Keystore / JSON File

会出来 “选择钱包” 按钮 点击之 选择刚才下载保存的 json文件

输入刚才自己设置的密码,点击解锁

钱包创建成功

账户地址

就是你的钱包地址 0xD2115fAbeadA3AFE193c3D908372C3EE8c647Be5

别人给你转账把此地址发给别人就可以了

你拥有了第一个钱包

3、谷歌浏览器插件方式安装钱包:MetaMask(自带梯子,你懂得!!!)

首先下载谷歌浏览器(百度一下,然后下载,下一步就可以了。如果安装了就跳过此步)

点击右上角三个点

依次选择 更多工具-扩展程序

点击   获取更多扩展程序,然后在搜索框输入 MetaMask

搜索出来以后点击  添加至CHROME,完成后右上角会出现一个小图标,点击之

点击Accept

然后划到底继续点击  Accept  然后输入新密码  第二个输入框确认密码,点击CREATE

有12单词,人家说了你最好记到纸上(这样换了电脑或环境一样可以找回钱包)

点击 I’VE COPIED IT SOMEWHERE SAFE另一个钱包创建成功了

 

可惜没钱,有两个钱包账户了,想过一把转账收款的瘾咋办呢?

别着急接着来

4、切换到测试网络

点击buy

继续点击 ROPSTEN TEST FAUCET

发钱了!!!!转个账试试吧

Kovan  Test网络获取地址https://gitter.im/kovan-testnet/faucet

 

点这里 : https://www.myetherwallet.com/#generate-wallet

 

点击   查看钱包信息 重复2.2步骤 copy钱包地址(注意切换到测试网络,现在余额为0)

然后点击 MetaMask  点击send

粘贴刚才的拷贝的钱包地址,输入转账个数

点击next

点submit转账成功

下边这个套路一样,自己下载对应的版本安装

https://github.com/bitpay/copay/releases/tag

mac版本安装没问题,win系统没成功,原因还不知道