主页 > 下载官方imtoken钱包 > 学习以太坊 Dapp 开发
学习以太坊 Dapp 开发
一、区块链1.分布式去中心化
比特币设计的初衷是避免依赖中心化机构。没有发行人,就不可能操纵发行号。由于没有中心化的信用机构,在电子货币运行的过程中,必然需要一种机制来识别运行在区块链上的行为(包括比特币的运行,或者其他运行在区块链上的行为)。业务),这个机制就是共识机制。比特币在完全去中心化的区块链上运行,使用 PoW(工作量证明),完美解决了拜占庭将军问题(在出现异常的情况下仍然可以达成共识)。由于基础网络架构是分布式的,单个节点不可能控制或破坏整个网络。只有掌握了网络中51%的算力(不是节点数),才有可能进行交易,成本大概会超过270亿美元。
2.无需信任
整个区块链网络中的数据是公开透明的,每个节点(参与者)都可以自由加入网络并下载到所有数据。任意两个节点之间的数据交换不需要相互信任,完全依赖于区块链中的交易历史和数据可追溯性,以及共识机制来保证数据交换的正确和不可逆的执行。
3.不可变和加密安全
类似于目前银行网银系统(尤其是企业网银系统)的加密机制,区块链的数据结构和交易过程中,使用了大量的公私钥进行加解密以确保数据的安全。基于这个技术基础,甚至可以应用组签名来保证共享数据的安全性。既然一切都有优点,也有缺点。根植于分布式网络架构和共识机制,在区块链上运行的交易确认时间会比较长(比特币的确认时间在 15 分钟左右),并发交易数量有限(每秒的交易数量为比特币为 7 淘宝上每秒并发交易数可达 10 万左右),区块容量限制(目前 1M,区块链扩容已在讨论中),监管难以介入,共识机制基于工作量证明是浪费系统资源和带宽问题。
4. 区块链技术阻止
区块是聚合区块链(公共分类账)中包含的交易信息的容器。它由一个包含元数据的块头和组成块体的一长串交易组成。区块头80字节,平均交易至少250字节,平均区块至少包含500笔交易。
块结构如下
交易(Tx)细节的结构如下
b.区块链
当节点接收到来自网络的传入块时,它会验证这些块,然后链接到现有块在区块链上,链接的形式如下:
因为每个区块都包含前一个区块的HASH值,这样就可以从创世区块开始当当前区块形成区块链时,每个区块必须按照时间顺序跟随前一个区块,因为当前区块不能在不知道前一个块的 HASH 值的情况下生成。改变一个已经在区块链中存在一段时间的块在计算上是不可行的比特币交易流程目录,因为如果它被改变,它之后的每个块都必须随之改变。这些特性让比特币的双花变得非常困难,而区块链是比特币最大的创新。
5. 比特币钱包比特币钱包生成 首先使用随机数生成器生成私钥。一般来说,这是一个 256 位的数字。有了这串数字,就可以对对应钱包地址中的比特币进行操作,所以一定要安全存放。私钥经过 SECP256K1 算法处理生成公钥。 SECP256K1 是一种椭圆曲线算法。当私钥已知时,可以计算出公钥,但是当已知公钥时,无法逆向计算私钥。这是保护比特币的算法基础。与 SHA256 一样,RIPEMD160 也是一种 Hash 算法。公钥哈希可以从公钥中计算出来,但是反过来是不可行的。将一个字节的地址版本号连接到公钥哈希头(对于比特币网络的公钥地址,该字节为“0”),然后对其进行两次SHA256操作,将结果的前4个字相加用作公钥哈希的校验值,并在其末尾连接。钱包地址是通过将上一步的结果用BASE58(比特币的定制版)编码得到的。流程图如下
b.转移
比特币钱包之间的转账是通过交易实现的。交易数据由外发钱包私钥的拥有者生成,也就是说有了私钥,钱包的比特币余额就可以花掉。生成交易的过程如下:
交易的原始数据包括“转账金额”和“转账钱包地址”,但这些还不够,因为无法证明交易的生成者有权使用“转账”的余额钱包地址”。所以原始数据需要用私钥签名。生成“转出钱包公钥”,此过程与生成钱包地址的步骤2相同。将“转出签名”和“转出公钥”添加到原始交易数据中,生成官方交易数据,以便将其广播到比特币网络进行转账。 二、以太坊1. 概念什么是以太坊
简单来说,以太坊是一种新的法律形式。现行法律的本质是合同。它是在人们(生活在社区中)和他们的领导人之间达成的,就彼此应该如何行动达成共识。个人之间也有一些合同。这些合同可以理解为一种私法。相应地,这条私法只对合同的参与者有效。
例如比特币交易流程目录,您与某人签订合同借给他一笔钱,但他最终违反了合同并且不打算偿还这笔钱。此时,您很可能会将另一方告上法庭。在现实生活中,诸如诉讼之类的事情往往很混乱,充满不确定性。将对方告上法庭通常也意味着支付高额费用聘请律师帮助您在法庭上辩论法律,而且过程通常很漫长。而且,即使您最终赢得了官司,您仍然可能会遇到问题(例如,拒绝执行法院命令)。
好消息是您和借款人写下了条款并签订了合同。但是立法者和合同起草者都必须面临一个不容忽视的挑战:即,理想情况下,法律或合同的内容应该是清晰明确的,但现有的法律和合同是由句子定义的,而句子是出了名的模棱两可。
因此,现行的法律制度一直存在两个巨大的问题:第一,合同或法律是由模棱两可的句子定义的,第二,执行合同或法律的成本非常高。大。
以太坊通过数字货币和编程语言的结合,解决了当前法律体系的两大难题。
以太坊系统本身有一种称为以太的数字货币。以太坊与著名的数字货币比特币有许多相似之处。两者都是无法伪造的数字储值货币,并且都以去中心化的方式运作,以确保货币供应不受一方控制。两者都可以像电子邮件一样以金钱的形式在世界范围内自由流通。而且,由于它们可以做传统货币做不到的事情,因此用户对其未来价值寄予厚望。
还有:
1.详情请阅读以太坊白皮书(中英文)。
2.以太坊教程
b.基础知识2. 工作流程 a.环境搭建建议使用Mac OS环境,否则会出现各种坑。安装 NodeJS,安装 Python。安装testrpc(用于测试环境)和安装go-ethereum(用于真实环境)。安装 solc。安装松露。
如果是windows,推荐使用ethbox工具一键安装以太坊开发环境的工具:ethbox
b.示例代码
contract Ballot {
//一个选民的构造体
struct Voter {
uint weight; // 权重(即他可以投几票)
bool voted; //是否已经投过票
address delegate; // 代表地址(他可以代表某个人进行投票)
uint vote; // index of the voted proposal
}
// 投票的提案的构造体
struct Proposal
{
bytes32 name; // 提案名称
uint voteCount; //获得的票数
}
address public chairperson;//会议主席
//地址 -选民 的map
mapping(address => Voter) public voters;
// 投票种类的动态数组
Proposal[] public proposals;
///构造函数
function Ballot(bytes32[] proposalNames) {
chairperson = msg.sender;//初始化会议主席
voters[chairperson].weight = 1;
//初始化所有的提案
for (uint i = 0; i < proposalNames.length; i++) {
proposals.push(Proposal({
name: proposalNames[i],
voteCount: 0
}));
}
}
// 给予投票权
function giveRightToVote(address voter) returns (bool b) {
if (msg.sender != chairperson || voters[voter].voted) {
//对于会议主席和已经投过票的选民这里不处理
return false;;
}
voters[voter].weight = 1;
return true;
}
/// 投票权转移函数
function delegate(address to) {
// 投票权转移的发起人
Voter sender = voters[msg.sender];
if (sender.voted)
throw;
//递归找到没有转移投票权的 选民
while (
voters[to].delegate != address(0) &&
voters[to].delegate != msg.sender
) {
to = voters[to].delegate;
}
if (to == msg.sender) {
throw;
}
//将发起人设置为已经投过票的状态
sender.voted = true;
//将代表设置为刚才递归获取的选民
sender.delegate = to;
Voter delegate = voters[to];
if (delegate.voted) {
//如果代表已经投过票就在他投票的提案的票数增加
proposals[delegate.vote].voteCount += sender.weight;
}
else {
//将代表的的票数增加
delegate.weight += sender.weight;
}
}
/// 投票函数
function vote(uint proposal) {
Voter sender = voters[msg.sender];
if (sender.voted)
throw;
sender.voted = true;
sender.vote = proposal;
//将投的提案票数增加
proposals[proposal].voteCount += sender.weight;
}
///获得票数最多的提案
function winningProposal() constant
returns (uint winningProposal)
{
uint winningVoteCount = 0;
for (uint p = 0; p < proposals.length; p++) {
if (proposals[p].voteCount > winningVoteCount) {
winningVoteCount = proposals[p].voteCount;
winningProposal = p;
}
}
}
}
解读
想要更深入的了解solidity语言,可以阅读官方文档。
c。使用 geth 部署合约启动测试节点 geth --testnet --fast --cache=512 --genesis CustomGenesis.json 控制台
CustomGenesis.json 用于将以太币分配给测试账户
{
"coinbase": "0x0000000000000000000000000000000000000000",
"difficulty": "0x20000",
"extraData": "",
"gasLimit": "0x2fefd8",
"nonce": "0x0000000000000042",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp": "0x00",
"alloc": {
"0xe49c283bc6bf92c5833cc981b97679238dd3b5da": {
"balance": "111111111000000000000000000000000000"
},
"0xd8927c296b3ebe454a6409770a0c323ec4ed23ba": {
"balance": "222222222000000000000000000000000000"
}
}
}
solc下的内容要替换成你的测试账号地址。 geth的具体用法请参考官方文档和源码介绍。
使用solc编译智能合约得到二进制代码
例如下面的代码
contract test {
function multiply(uint a) returns(uint d) {
return a * 7;
}
}
输入<在geth中
source = "合约测试 { 函数乘法(uint a) 返回(uint d) { return a * 7; } }"
clientContract = eth.compile.solidity(source)。测试
编译器返回结果的JSON格式如下
其中,
编译器返回的 JSON 结构反映了两种不同的合约部署路径。信息信息实际存在于中心化云端,作为元数据信息公开验证合约代码在区块链中的执行情况。代码信息通过创建交易部署到区块链上。
使用solc编译智能合约并获取二进制代码
在部署合约之前,请确保您有一个解锁的账户和账户余额,因为在部署合约的过程中会消耗以太币。输入web3.fromWei(eth.getBalance(eth.accounts[0]),"ether")查看账户余额。
解锁帐户personal.unlockAccount(eth.accounts[0])
获取帐号
primaryAddress = eth.accounts[0]
定义一个abi(abi是js数组,否则不成功)
abi = [{ 常量:false,输入:[{ name: 'a', type: 'uint256' } ]}]
创建智能合约
MyContract = eth.contract(abi)
发送交易部署合约
contract = MyContract.new({ from: primaryAddress, data:"0x6060604052602a8060106000396000f3606060405260e060020a6000350463c6888fa18114601a575b005b6007600435026090308}}"}
如果被挂起,说明你的矿工没有在交易中
启动一个矿工
miner.setEtherbase(eth.primaryAddress) //设置挖矿账号
miner.start(8)
eth.getBlock("pending", true).transactions
此时发现交易已经在区块中了
@ >
但是会发现交易还在等待中,因为没有人协助计算和验证交易区块。此时,只需要再启动一个矿工即可。
miner.start (8)
与合约交互 Multiply7 = eth.contract(clientContract.info.abiDefinition);
var myMultiply7 = Multiply7.at(contract.address);
myMultiply7.multiply.call(3)
或
myMultiply7.multiply.sendTransaction(3, {from: contract.address}) d.使用松露框架
使用松露部署智能合约的步骤:
truffle init (in a new directory) => 创建truffle项目目录结构,编写合约代码,保存到contracts/YourContractName.sol文件中。
例如Ballot.sol,此时找到migrations文件夹,在deploy_contracts.js文件中添加deployer.deploy(Ballot); truffile compile 编译合约代码。启动一个以太坊节点(例如在另一个终端运行 testrpc)。松露迁移(在松露项目目录中)。 1. 编写单元测试
在 test 文件夹中新建一个 ballot.js 文件
contract('Ballot',function(accounts)){
//accounts是所以账户得数值
it("获取投票权",function(){
var meta = Ballot.deployed();
return meta.giveRightToVote(accounts[1]).then(function(b){
assert.equal(Boolean(b),true,"获取投票权失败");
});
});
}
在项目根目录运行truffle test,应该可以看到测试通过了,如果使用自己构建的ballot对象,可以这样写:
contract('Ballot',function(accounts)){
//accounts是所以账户得数值
it("获取投票权",function(){
var proposals = [];
proposals.push("proposal0");
Ballot.new(proposals).then(function(meta){
return meta.giveRightToVote(accounts[1]).then(function(b){
assert.equal(Boolean(b),true,"获取投票权失败");
});
});
});
}
2.为合约接口创建合约
在app目录下,可以编写自己的html和js文件。 js与智能合约的交互与单元测试基本相同。比如界面上有一个输入框和一个按钮,就可以得到选民的投票权。
Ballot App
Ballot
Example Truffle Dapp
Send
app.js中的代码是
function getRight() {
var account = document.getElementById("account").value;
var meta = Ballot.deployed();
meta.giveRightToVote(account).then(function(b){
if(Boolean(b)){
setStatus("Get Right Vote Success");
}else{
setStatus("Get Right Vote Error");
}
}).catch(function(e){
setStatus("Get Right Vote Error");
console.log(e);
});
};