分类 技术前沿 下的文章 - 六币之门
首页
视频教程
网站导航
活动日历
关于我们
用户投稿
推荐
新闻动态
搜 索
1
融资周报 | 公开融资事件11起;加密技术公司Toposware完成500万美元融资,Polygon联创参投
107 阅读
2
六币日报 | 九只比特币ETF在6天内积累了9.5万枚BTC;贝莱德决定停止推出XRP现货ETF计划
73 阅读
3
六币日报 | 美国SEC再次推迟对灰度以太坊期货ETF做出决定;Do Kwon已出黑山监狱等待引渡
68 阅读
4
融资周报 | 公开融资事件27起;L1区块链Monad Labs完成2.25亿美元融资,Paradigm领投
67 阅读
5
【ETH钱包开发06】查询某个地址的交易记录
43 阅读
新闻动态
每日快报
一周精选
融资情况
项目投研
自治组织
数字藏品
去中心化应用
去中心化游戏
去中心化社交
去中心化金融
区块链交易所
科普知识
小白入门
用户手册
开发文档
行业报告
技术前沿
登录
搜 索
标签搜索
新闻
日报
元歌Eden
累计撰写
1,087
篇文章
累计收到
0
条评论
首页
栏目
新闻动态
每日快报
一周精选
融资情况
项目投研
自治组织
数字藏品
去中心化应用
去中心化游戏
去中心化社交
去中心化金融
区块链交易所
科普知识
小白入门
用户手册
开发文档
行业报告
技术前沿
页面
视频教程
网站导航
活动日历
关于我们
用户投稿
推荐
新闻动态
用户登录
登录
找到
109
篇与
技术前沿
相关的结果
2023-03-24
椭圆曲线加密算法
椭圆曲线密码学(Elliptic curve cryptography),简称ECC,是一种建立公开密钥加密的算法,也就是非对称加密。类似的还有RSA,ElGamal算法等。ECC被公认为在给定密钥长度下最安全的加密算法。比特币中的公私钥生成以及签名算法ECDSA都是基于ECC的。下面简单介绍ECC以及ECDSA的原理。从公钥加密说起 公钥加密,也称非对称加密。可以说它现在是现代网络安全或者网络信任链的基础。公钥加密最大的特征就是通信双方各有一对公私钥,这一对公私钥有着千丝万缕的数学关系。每个人保存自己的私钥,公开自己的公钥。这样做的好处是不怕通信线路被窃听,因为攻击者拿到公钥是无法解出密文的。公私钥的基本使用场景主要有两种:假设通信双方叫Alice(公钥A、私钥a)和Bob(公钥B、私钥b)。公钥加密,私钥解密 Alice写了一封信,她不想让别人知道。于是它用Bob的公钥B对信的明文做了加密,密文为m。之后发送给了Bob。 Bob收到密文m,用自己的私钥b对密文解密,正确的读出了信的内容。 整个过程中,即使窃听者拿到密文m、两个人的公钥A、B都没有什么用,无法解密出任何东西。事实上,只有拥有私钥b的人才能解密出这份信息。换个角度来说,每个人都可以拥有Bob的公钥B,也就是说,每个人都可以创造一份只有Bob可以使用或者说只对Bob来说有效的信息。私钥加密,公钥解密 Alice写了一份公开声明文件,她用自己的私钥a对文件加了密,生成加密文件m,公布在自己的网站中。 Bob下载了这份声明文件,并用Alice的公钥A进行解密,正确的读出文件内容。 这个过程听起来有点奇怪,Alice既然公布的是声明文件,是想让别人阅读的,而且每个人都可以拿到Alice的公钥A,那么为什么还要加密呢?确实,每个人都可以对文件解密,可是这里的目的主要不是解密,而是对这份文件的来源验证,证明它肯定是由Alice发出的声明。即使文件被恶意篡改,那么此时再拿公钥A解密,就是无效的,由此可证明信息被改动过了,并不是Alice的原来文件。用这种方式使用公私钥可以证明信息的来源并且有不可否定的特性。(即Alice不能否认此信息不是由她发出的,因为只有私钥a可以产生加密文件m) 以上是使用公钥加密算法的基础场景,但事实上用上述方法进行通信还远远不够,例如需要提高加密速度,需要先对文件进行hash;再如不能抵御中间人攻击,(即获取的公钥不一定是正确的)需要引入证书,不过这些不在本文讨论范围之内。下面我们来看ECC是如何产生密钥对的。椭圆曲线这一节让我们来了解一些数学知识。一般来说,椭圆曲线可以用下列方程式表示,a,b,c,d为系数(a≠0,没有重根)例如,当a=1,b=0,c=-2,d=4时,所得到的椭圆曲线为:椭圆曲线下图所示。$E_1:y^2=x^3-2x+4$曲线其实椭圆曲线并不是我们高中学习的椭圆形状,其名字的由来是因为椭圆曲线的描述方程,类似于计算一个椭圆周长的方程。这里用于加密的椭圆曲线的定义是一个特殊情况,完整定义参考这里有了图像,我们接下来就可以搞一搞事情了????椭圆曲线的加法在这里首先要介绍一下群的概念。群是一种代数结构,由一个集合以及一个二元运算所组成。已知集合和运算(G,*)如果是群则必须满足如下要求封闭性:∀a,b∈G,a * b ∈ G 结合性:∀a,b,c∈G ,有 (a * b) * c = a * (b * c) 单位元:ョe∈G, ∀a ∈G,有e * a = a * e = a 逆元:∀a ∈G ,ョb∈G 使得 a * b = b * a = e 另外,有一种特殊的群叫阿贝尔群,它除了上面的性质还满足交换律公理 a * b = b * a举个例子,在整数范围内的加法运算就是一个阿贝尔群(Z,+)。封闭性:a和b是整数,那么a+b肯定是整数。 结合性:(a + b) + c = a + (b + c)。 单位元:0即为单位元,因为对于所有整数a, a + 0 = 0 + a = a。 逆元: a的逆元为-a,因为a + (-a) = 0,即单位元。 所以(Z,+)是阿贝尔群。现在,我们来定义椭圆曲线上的加法。现在有椭圆曲线,曲线上的点P和Q。过P和Q做一条直线,交椭圆曲线为点R',再过R'点做垂直于X轴的直线,交曲线另一点为R,定义P + Q = R。如下图所示。若P=Q,则为过P点的切线交于椭圆曲线为R'。如下图所示。 这样,称R = 2P。类似的,3P = P + P + P = P + 2P = P + R。也就是说,当给定点P时,“已知数x求点xG的运算”不难,因为有加法的性质,运算起来可以比较快。但反过来,“已知点xG求x的问题”则非常困难,因为只能遍历每一个x做运算。这就是椭圆曲线密码中所利用的“椭圆曲线上的离散对数问题”。要想使这个运算满足阿贝尔群的性质,我们还要引入一个无穷远点O,可以把它理解为平行直线的交点(如果感觉难以理解,请参考无穷远点的定义),我们把这个O点作为单位元。(方便理解,你可以当做所有平行于y轴的直线交于O点)。有了上述无穷远点的定义,不难证明椭圆曲线上的加法为一个阿贝尔群。椭圆曲线上的离散对数问题 椭圆曲线密码利用了上述“运算”中的“椭圆曲线上的离散对数问题”的复杂度,就像RSA利用了“大数质因数分解”的复杂度,以及EIGamal密码的Diffie-Hellman密钥交换利用了“有限域上的离散对数问题”的复杂度一样。椭圆曲线上的离散对数问题:已知 椭圆曲线E 椭圆曲线E上一点G(基点) 椭圆曲线E上的一点xG(x倍的G) 求解 x 这个问题的难度保证了椭圆曲线密码的安全性。有限域上的椭圆曲线 到这里,椭圆曲线的定义及运算都是实数范围内的,其实椭圆曲线密码所使用的运算,是在有限域上。有限域是指对于某个给定的质数p,由0,1,2,.....,p-1共p个元素所组成的整数集合中定义的加减乘除运算。此运算使用的是模运算。我们来看一个具体的例子:当这个椭圆曲线位于实数域R上时,图像如下图所示,是一条光滑的曲线。同样是这条曲线,当位于有限域上时,写作:即左侧与右侧的结果除以23的余数相等,也叫左侧与右侧的数值模23同余。于是上述图像并不是一条曲线,而是一些离散的点。图像如下图所示。如果我们以椭圆曲线上的点P =(3,10)为基点,按照椭圆曲线“加法”运算的规则计算2P,3P,4P...结果如下图所示。我们可以看到,所产生的点可以说是无规律可言,例如点P = (3,10),点23P = (9,7)。在这里求离散对数问题就相当于已知点(3,10)和点(9,7),求23。在这个例子中p=23,问题还不难解,如果当p数值非常大时,要求出这个解是十分困难的。产生公钥和私钥在椭圆曲线加密中,给定椭圆曲线E,基点G和点xG,我们称xG为公钥,x值为私钥。由椭圆曲线性质可知,已知私钥求公钥很简单,而已知公钥求私钥几乎是不可能的事情。椭圆曲线密码的应用有了密钥对,就可以做很多公钥加密的事情了,比如最基本的加密通信,验证数字签名等。这里仅介绍数字签名,其他的原理本质上也都是一样的。数字签名:椭圆曲线DSA(ECDSA)依然假设Alice要发布公开文件,并对此文件进行数字签名。Bob需要验证该签名。(以下涉及计算的部分都是求模运算)生成数字签名Alice根据随机数 和基点 求出点 = (x,y) Alice根据随机数 、消息 的散列值 、私钥 计算 最后,Alice将消息 、点 和 发送给Bob,其中点 和 就是数字签名 验证数字签名Bob接收到消息 、点 和 Bob根据消息 求出散列值 最后,Bob进行以下计算: 最后把R和rG进行比较,如果相等,则验证签名正确,否则说明是错误的数字签名。 验证原理这里关键的一点是Alice签名的时候引入了随机数 ,而利用公钥A=aG的特性,在算式中只有A可以消除随机变量r的因素。引入随机数也提高了安全性,即便对于同一条消息,只要改变随机数R,所得到的签名也会随之改变。至此,我们对于椭圆加密ECC的原理以及ECDSA数字签名有了大致的了解。参考资料:ECC椭圆曲线详解图解密码技术第三版
2023年03月24日
5 阅读
0 评论
0 点赞
2023-03-24
使用Remix编译和部署以太坊智能合约
Remix 是一个开源的 Solidity 智能合约开发环境,提供基本的编译、部署至本地或测试网络、执行合约等功能。Solidity 是 以太坊Ethereum 官方设计和支持的开发语言,专门用于编写智能合约。本文希望将一个很简单的代币合约(只能发行和转账),部署在本地和测试网络上,测试下它的功能。详细描述使用 Remix 的步骤及使用上可能碰到的问题。之前开发过以太坊Ethereum智能合约,但没有记录过开发的过程和碰到的问题,觉得挺可惜。这次重新开始,从最基础开始,一步步学习。开发环境不需要安裝,直接在任何浏览器启动 Remix。取得代币合约代币合约的范例很多,Ethereum 官网有提供一个最小可执行的代币合约(MINIMUM VIABLE TOKEN):pragma solidity ^0.4.0; contract MyToken { /* This creates an array with all balances */ mapping (address => uint256) public balanceOf; /* Initializes contract with initial supply tokens to the creator of the contract */ function MyToken(uint256 initialSupply) public { balanceOf[msg.sender] = initialSupply; // Give the creator all initial tokens } /* Send coins */ 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 } } 复制代码这个 MyToken 合约真的很简单,只能做两件事:创建代币:发起合约时创建指定数量的代币,代币拥有者是发起合约的 Ethereum 帐户 转移代币:转移指定数量的代币到指定的 Ethereum 帐户 至于一个完整的代币合约,可参考ERC20 Token使用手冊。使用 Remix 编译合约点右上角 + 新增一个合约 名称任意只要扩展名是 “.sol”。 复制合约內容到该合约并编译 Remix 默认设置会自动编译,只要旁边没有蹦出红色的 error 提示就代表编译成功。 在本地部署合约1.设置网络 点选左上的 run。Environment 选择 JavaScript VM 代表所有资料都是存在本地(功能类似 testrpc)。它会提供 5 个虚拟账户每个有 100 ETH,随便选择一个账户(要记住后面一直要用)。2.发送交易部署合约 选择 MyToken。可以看到 create 按钮。且已根据合约內容显示必须输入 initialSupply(也就是要发行的代币数量)。输入一个数目点create,就可以发送交易部署合约。合约部署成功后,可以看到合约的使用界面。Remix 会自动根据合约的內容,产生对应的合约使用界面。可以看到合约有两个功能:balanceOf(查询余额) 和 transfer(转移代币)。底下可以看到 log(记录每一次的操作)。实际上部署合约是通过一个 Ethereum 交易完成,点 Details 可以看到这笔交易详细资料。执行合约 — 查询余额1.选择刚刚发起合约的账户可以点右边的按钮复制2.输入账户 注意要用 “” 把账户括起來,示例:"0xca35b7d915458ef540ade6068dfe2f44e8fa733c" 复制代码3.点击 balanceOf可以看到执行结果,也就是目前这个账户的代币余额。可能的错误情況说明一点,因为数据传输是用 JSON 格式,所以要加上 “”。如果忘了 “” 就会在 log 中看到错误提示:执行合约 — 转移代币1.选择要输出的账户 选择刚刚发起的合约的账户。2.输入要转入的账户 选择並复制另一个账户。在合约界面 transfer 后面的输入位置,输入转入账户和要转移的代币数量。账户同样需要用 “” 括起來,示例:"0x4b0897b0513fdc7c541b6d9d7e929c4e5364d2db", 10 复制代码3.点击 transfer 点击 transfer,成功后会看到 log 更新。4.确认余额更新 这时在查询转入账户的余额,就可以看到代币余额增加啦!错误情況 如果选择要转出的账户代币余额不足,这个交易就会失败,会在 log 看到错误提示。在测试网络部署合约1.安裝 MetaMask 首先,要连到测试网络,这就要安裝 MetaMask。它是浏览器端的 Ethereum 钱包,可以连結 Ethereum 公共和测试网络。安装后需要建立 Ethereum 账号,这个这里就不细讲了。成功启动后是这样的。我们选择 Ropsten Test Net2.选择测试网络回到 Remix,这次 Environment 选择 Injected Web3,Remix 会自动连接 MetaMask。成功连接后会看到和 MetaMask 相同账号和 Ether 余额3.部署合约 接着用同样的方式,按 create 部署合约,就会看到 MetaMask 的弹出窗口。直接按 submit 发送交易。稍等片刻(需要等交易被确认),部署成功后合约的使用界面就会出来。ok,现在可以用同样的方式使用合约啦!总结下Remix 提供一个 Solidity 智能合约的开发环境,可以方便的编译、部署、执行甚至找错,适合编程经验不多的初学者。但无法做到版本控制、测试及和其他开发工具一起使用等,实际上要开发 DApp,使用 Truffle3、Ganache、web3.js 来编译和部署合约比较方便和专业些更适合开发人员。推荐一个适合区块链新手的以太坊DApp开发教程:xc.hubwiz.com/course/5a95…如果想加入以太坊技术开发群可以加微信:cuixuebin2,拉你入群。
2023年03月24日
7 阅读
0 评论
0 点赞
2023-03-24
以太坊 DApp 开发入门,如何搭建一个区块链投票系统。
第一节 概述对于初学者,需要了解以太坊开发相关的基本概念,另外就是如何构建一个基于以太坊的完整去中心化应用例如一个区块链投票系统。通过学习,你将掌握:以太坊区块链的基本知识 开发和部署以太坊合约所需的软件环境 使用高级语言(solidity)编写以太坊合约 使用NodeJS编译、部署合约并与之交互 使用Truffle框架开发分布式应用 使用控制台或网页与合约进行交互 以太坊开发的前序知识要求为了顺利完成本课程,最好对以下技术已经有一些基本了解:一种面向对象的开发语言,例如:Python,Ruby,Java... 前端开发语言:HTML/CSS/JavaScript Linux命令行的使用 数据库的基本概念 第二节 简介我们将会构建一个去中心化的(Decentralized)投票应用。利用这个投票应用, 用户可以在不可信(trustless)的分布环境中对特定候选人投票,每次投票都会被记录在区块 链上:所谓去中心化应用(DApp:Dcentralized Application),就是一个不存在中心服务器 的应用。在网络中成百上千的电脑上,都可以运行该应用的副本,这使得它几乎不可能 出现宕机的情况。基于区块链的投票是完全去中心化的,因此无须任何中心化机构的存在。第三节 开发迭代涵盖应用开发的整个过程,我们将通过三次迭代来渐进地引入区块链应用 开发所涉及的相关概念、语言和工具:Vanilla:在第一个迭代周期,我们不借助任何开发框架,而仅仅使用NodeJS来进行应用开发, 这有助于我们更好地理解区块链应用的核心理念。 Truffle:在第二个迭代周期,我们将使用最流行的去中心化应用开发框架Truffle进行开发。 使用开发框架有助于我们提高开发效率。 Token:在第三个迭代周期,我们将为投票应用引入代币(Token) —— 现在大家都改口 称之为通证了 —— 都是ICO惹的祸。代币是公链上不可或缺的激励机制,也是区块链 应用区别于传统的中心化应用的另一个显著特征。 为什么选择投票应用?之所以选择投票作为我们的第一个区块链应用,是因为集体决策 —— 尤其是投票机制 —— 是以太坊的 一个核心的价值主张。另一个原因在于,投票是很多复杂的去中心化应用的基础构件,所以我们选择了投票应用作为学习区块链 应用开发的第一个项目。第四节 初识区块链如果你熟悉关系型数据库,就应该知道一张数据表里可以包含很多行数据记录。例如,下面的数据表中 包含了6条交易记录:本质上,区块链首先就是一个分布式(Distributed)数据库,这个数据库维护了一个不断增长的记录列表。 现在,让我们对数据进行批量(batch)存储,比如每批 100 行,并将各存储批次连接起来,是不是就像一条链?在区块链里,多个数据记录组成的批次就被称为块(block),块里的每一行数据记录就被称为交易(transaction):最开始的那个块,通常被称为创世块(genesis block),它不指向任何其他块。不可篡改性区块链的一个显著特点是,数据一旦写入链中,就不可篡改重写。在传统的关系型数据库中,你可以很容易地更新一条数据记录。但是,在区块链中,一旦数据写入就无法 再更新了 —— 因此,区块链是一直增长的。那么,区块链是如何实现数据的不可篡改特性?这首先得益于哈希(Hash)函数 —— 如果你还没接触过哈希函数,不妨将它视为一个数字指纹的计算函数: 输入任意长度的内容,输出定长的码流(指纹)。哈希函数的一个重要特性就是,输入的任何一点微小变化,都会 导致输出的改变。因此可以将哈希值作为内容的指纹来使用。 你可以点击这里进一步了解哈希函数。由于区块链里的每个块都存储有前一个块内容的哈希值,因此如果有任何块的内容被篡改,被篡改的块之后 所有块的哈希值也会随之改变,这样我们就很容易检测出区块链的各块是否被篡改了。去中心化的挑战一旦完全去中心化,在网络上就会存在大量的区块链副本(即:全节点),很多事情都会变得比之前中心化 应用环境复杂的多,例如:如何保证所有副本都已同步到最新状态? 如何保证所有交易都被广播到所有运行和维护区块链副本的节点计算机上? 如何防止恶意参与者篡改区块链 ...... 在接下来的课程中,通过与经典的C/S架构的对比,我们将逐步理解去中心化应用的核心思路, 并掌握如何构建以太坊上的去中心化应用。第五节 C/S架构以服务器为中心理解去中心化应用架构的最好方法,就是将它与熟悉的Client/Server架构进行对比。如果你是一个web开发者, 应该对下图很了解,这是一个典型的Client/Server架构:一个典型web应用的服务端通常由 Java,Ruby,Python 等等语言实现。前端代码由 HTML/CSS/JavaScript 实现。 然后将整个应用托管在云端,比如 AWS、Google Cloud Platform、Heroku....,或者放在你租用的一个VPS 主机上。用户通过客户端(Client)与 web 应用(Server)进行交互。典型的客户端包括浏览器、命令行工具(curl、wget等)、 或者是API访问代码。注意在这种架构中,总是存在一个(或一组)中心化的 web 服务器,所有的客户端都需要 与这一(组)服务器进行交互。当一个客户端向服务器发出请求时,服务器处理该请求,与数据库/缓存进行交互, 读/写/更新数据库,然后向客户端返回响应。这是我们熟悉的中心化架构。在下一节,我们将会看到基于区块链的去中心化架构的一些显著区别。第六节 去中心化架构——彼此平等的节点下图给出了基于以太坊的去中心化应用架构:你应该已经注意到,每个客户端(浏览器)都是与各自的节点应用实例进行交互,而不是向 一个中心化的服务器请求服务。在一个理想的去中心化环境中,每个想要跟DApp交互的人,都需要在他们的计算机或手机上面运行 一个的完整区块链节点 —— 简言之,每个人都运行一个全节点。这意味着,在能够真正使用一个 去中心化应用之前,用户不得不下载整个区块链。不过我们并非生活在一个乌托邦里,期待每个用户都先运行一个全节点,然后再使用你的应用是不现实的。 但是去中心化背后的核心思想,就是不依赖于中心化的服务器。所以,区块链社区已经出现了 一些解决方案,例如提供公共区块链节点的Infura, 以及浏览器插件Metamask等。通过这些方案, 你就不需要花费大量的硬盘、内存和时间去下载并运行完整的区块链节点,同时也可以利用去中心化 的优点。我们将会以后的课程中对这些解决方案分别进行评测。第七节 以太坊——世界计算机以太坊是一种区块链的实现。在以太坊网络中,众多的节点彼此连接,构成了以太坊网络:以太坊节点软件提供两个核心功能:数据存储、合约代码执行。在每个以太坊全节点中,都保存有完整的区块链数据。以太坊不仅将交易数据保存在链上,编译后 的合约代码同样也保存在链上。以太坊全节点中,同时还提供了一个虚拟机来执行合约代码。交易数据以太坊中每笔交易都存储在区块链上。当你部署合约时,一次部署就是一笔交易。当你为候选者投票时,一次投票 又是另一笔交易。所有的这些交易都是公开的,每个人都可以看到并进行验证。这个数据永远也无法篡改。为了确保网络中的所有节点都有着同一份数据拷贝,并且没有向数据库中写入任何无效数据,以太坊 目前使用工作量证明 (POW:Proof Of Work)算法来保证网络安全,即通过矿工挖矿(Mining)来达成共识(Consensus)—— 将数据同步到所有节点。工作量证明不是达成共识的唯一算法,挖矿也不是区块链的唯一选择。现在,我们只需要了解,共识是指各节点 的数据实现了一致,POW只是众多用于建立共识的算法中的一种,这种算法需要通过矿工的挖矿来实现非可信环境下的 可信交易。共识是目的,POW是手段。合约代码以太坊不仅仅在链上存储交易数据,它还可以在链上存储合约代码。在数据库层面,区块链的作用就是存储交易数据。那么给候选者投票、或者检索投票结果的逻辑放在哪儿呢? 在以太坊的世界里,你可以使用Solidity语言来编写业务逻辑/应用代码(也就是合约:Contract), 然后将合约代码编译为以太坊字节码,并将字节码部署到区块链上:编写合约代码也可以使用其他的语言,不过 Solidity是到目前为止最流行的选择。以太坊虚拟机以太坊区块链不仅存储数据和代码,每个节点中还包含一个虚拟机(EVM:Ethereum Virtual Machine)来执行 合约代码 —— 听起来就像计算机操作系统。事实上,这一点是以太坊区别于比特币(Bitcoin)的最核心的一点:虚拟机的存在使区块链迈入了2.0 时代,也让区块链第一次成为应用开发者友好的平台。JS开发库为了便于构建基于web的DApp,以太坊还提供了一个非常方便的JavaScript库web3.js,它封装了以太坊节点的API 协议,从而让开发者可以轻松地连接到区块链节点而不必编写繁琐的RPC协议包。所以,我们可以在常用的JS框架 (比如 reactjs、angularjs 等)中直接引入该库来构建去中心化应用:有兴趣可以继续: xc.hubwiz.com/course/5a95…
2023年03月24日
6 阅读
0 评论
0 点赞
2023-03-24
18年给自己做个Token吧
注:一般大家都普遍喜欢把 Token 叫成 代币,但是这样讲很不准确,如果非要叫成中文,我更认同 通证 这种理解。但为了保持原汁原味,不必非得翻译过来叫,所以本文统一保持英文的形式。一般 Token 制作的门槛其实没有多高,所以大家完全都有能力可以去制作出自己命名的 Token。不过你也别指望啥也不学就能做出一些拥有额外逻辑的 Token,比如众筹合约等,所以想要做的与众不同,那么就需要花些成本。下面就直奔主题,我们不需要了解如何编写智能合约,因为以太坊提供的 ERC20 协议已经足够傻瓜式了,做一个简单的 Token 官方就有一个标准的智能合约代码作为示例,那么我们只需要知道制作的流程就行了。啰嗦一句,其实学习其他的技术知识也是如此,我们不要急于追求很内在的东西,我们需要 正反馈 式学习法,先做出一些简单的 Demo,逐步在建立自信心和激发热情的同时不断深入学习。安装 MetaMask我们首先需要安装一个浏览器的插件 MetaMask,该插件作者非常 nice,主流的三大浏览器(Google、FireFox、Opera)上都可以安装这款实用的插件。安装这款插件的过程就不赘述了,现在假定我们已经装好了,点开该插件,经过两次 Accept 同意条款的操作后,进入创建账户的页面。注意图上的三处箭头第一处箭头表示我们目前是处于 Ropsten Test Net 测试网络,与平常大家在用的以太坊主网络的主要区别就仅仅是大家只承认主网络上的以太币价值,而该测试网络主要用来进行开发测试。 第二处箭头表示新建一个账户合约,作为以太坊网络上的一个合法用户。 第三处箭头表示导入一个账户合约,假如你在该网络上有账户合约的话。 新建合约账户在创建账户页面上输入自己的大于八位字符的密码后,进入 助记词 页面,这些助记词是唯一能帮助你保存自己账户合约的密钥,妥善保管。购买以太币不要慌,不是让你真的花钱去买,只需要在 MetaMask 提供的网站上点几下按钮就能获取到以太币(毕竟这些测试网络上的以太币没有实际价值)。保存完助记词后我们就会进入到账户主页面,我们可以看到我们的账户上余额是零,点击箭头1的购买按钮,进入确认页面再点击上图中的箭头1按钮,进入购买页面,网址是 Test Ether Faucet点击箭头1按钮,既可以获取到一个以太币(按一次获取一个),我获取了6个以太币,箭头2处即是转账交易记录。OK,我们先暂时放一放 MetaMask,接下来让我们去玩玩 Remix!认识 Remix IDERemix 是一个基于浏览器的 Solidity IDE,基本的智能合约代码的开发调试在这上面进行是相当舒服的。Remix - Solidity IDE第一处箭头是项目目录栏,可以在这里创建文件目录 第二处箭头是代码栏,我们的合约代码就在这里编写 第三处箭头是日志栏,部署调试的日志输出都在这里显示 第四处箭头是调试栏,对合约的部署、调试等操作都在这里进行 需要熟悉这个工具吗?当然,而且越熟悉越好,但不是现在,别忘了我们现在的目标是制作自己的 Token。Token 合约以太坊官方网站上有一份标准的 Token 合约供学习者参考,而且也有很详细的教程教大家如何去部署自己的 Token。Create a cryptocurrency contract in Ethereum本文与官方不同的是我们使用 轻钱包 MetaMask 和在线开发环境 Remix 进行开发调试部署,官方的以太坊钱包对于初学者来说有个挺苦恼的地方,同步主网络或者测试网络的全节点数据很慢,而且占用磁盘空间较大。初次体验尽量还是选择轻松的方式,不要给自己留下坏心情 :)我们将官方的 Token 合约代码拷贝到 Remix 的代码栏中,合约代码这里也贴一下:pragma solidity ^0.4.16; interface tokenRecipient contract TokenERC20 { // Public variables of the token string public name; string public symbol; uint8 public decimals = 18; // 18 decimals is the strongly suggested default, avoid changing it uint256 public totalSupply; // This creates an array with all balances mapping (address => uint256) public balanceOf; mapping (address => mapping (address => uint256)) public allowance; // This generates a public event on the blockchain that will notify clients event Transfer(address indexed from, address indexed to, uint256 value); // This notifies clients about the amount burnt event Burn(address indexed from, uint256 value); /** * Constructor function * * Initializes contract with initial supply tokens to the creator of the contract */ function TokenERC20( uint256 initialSupply, string tokenName, string tokenSymbol ) public { totalSupply = initialSupply * 10 ** uint256(decimals); // Update total supply with the decimal amount balanceOf[msg.sender] = totalSupply; // Give the creator all initial tokens name = tokenName; // Set the name for display purposes symbol = tokenSymbol; // Set the symbol for display purposes } /** * Internal transfer, only can be called by this contract */ function _transfer(address _from, address _to, uint _value) internal { // Prevent transfer to 0x0 address. Use burn() instead require(_to != 0x0); // Check if the sender has enough require(balanceOf[_from] >= _value); // Check for overflows require(balanceOf[_to] + _value > balanceOf[_to]); // Save this for an assertion in the future uint previousBalances = balanceOf[_from] + balanceOf[_to]; // Subtract from the sender balanceOf[_from] -= _value; // Add the same to the recipient balanceOf[_to] += _value; Transfer(_from, _to, _value); // Asserts are used to use static analysis to find bugs in your code. They should never fail assert(balanceOf[_from] + balanceOf[_to] == previousBalances); } /** * Transfer tokens * * Send `_value` tokens to `_to` from your account * * @param _to The address of the recipient * @param _value the amount to send */ function transfer(address _to, uint256 _value) public { _transfer(msg.sender, _to, _value); } /** * Transfer tokens from other address * * Send `_value` tokens to `_to` on behalf of `_from` * * @param _from The address of the sender * @param _to The address of the recipient * @param _value the amount to send */ function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) { require(_value <= allowance[_from][msg.sender]); // Check allowance allowance[_from][msg.sender] -= _value; _transfer(_from, _to, _value); return true; } /** * Set allowance for other address * * Allows `_spender` to spend no more than `_value` tokens on your behalf * * @param _spender The address authorized to spend * @param _value the max amount they can spend */ function approve(address _spender, uint256 _value) public returns (bool success) { allowance[msg.sender][_spender] = _value; return true; } /** * Set allowance for other address and notify * * Allows `_spender` to spend no more than `_value` tokens on your behalf, and then ping the contract about it * * @param _spender The address authorized to spend * @param _value the max amount they can spend * @param _extraData some extra information to send to the approved contract */ function approveAndCall(address _spender, uint256 _value, bytes _extraData) public returns (bool success) { tokenRecipient spender = tokenRecipient(_spender); if (approve(_spender, _value)) { spender.receiveApproval(msg.sender, _value, this, _extraData); return true; } } /** * Destroy tokens * * Remove `_value` tokens from the system irreversibly * * @param _value the amount of money to burn */ function burn(uint256 _value) public returns (bool success) { require(balanceOf[msg.sender] >= _value); // Check if the sender has enough balanceOf[msg.sender] -= _value; // Subtract from the sender totalSupply -= _value; // Updates totalSupply Burn(msg.sender, _value); return true; } /** * Destroy tokens from other account * * Remove `_value` tokens from the system irreversibly on behalf of `_from`. * * @param _from the address of the sender * @param _value the amount of money to burn */ function burnFrom(address _from, uint256 _value) public returns (bool success) { require(balanceOf[_from] >= _value); // Check if the targeted balance is enough require(_value <= allowance[_from][msg.sender]); // Check allowance balanceOf[_from] -= _value; // Subtract from the targeted balance allowance[_from][msg.sender] -= _value; // Subtract from the sender's allowance totalSupply -= _value; // Update totalSupply Burn(_from, _value); return true; } } 复制代码部署合约接下来我们先选择好我们的编译器的版本,对应合约代码首行的版本号 pragma solidity ^0.4.16点击箭头1的标签页,进入设置界面,然后点击箭头2选择相应的编译器版本,这里即选择 0.4.16。然后点击编译标签(Compile),会看到已经编译成功然后点击运行标签(Run),进行部署操作第一处箭头选择部署环境,这边会自动检测到我们的 MetaMask 当前所处的网络(Ropsten Test Net)。 第二处箭头输入我们 Token 的一些基本信息 第一个参数表示 Token 总发行量,我这里随便填了一千万个 第二个参数表示 Token 名称 第三个参数表示 Token 符号,一般在流通过程中均以该符号作为 Token 的标识 第三处箭头点击即创建部署交易单,开始最终的部署 这里唯一可以改的是 Gas Limit 和 Gas Price,一般来讲这两个数据会自动根据当前合约的复杂度和市场平均水准生成。所以一般不需要去改这两个值,如果是囊中羞涩,改低一点也是可以的,但是可能会出现 Gas 被消耗完的情况(Gas 一旦被消耗完而合约仍未部署到网络上,那么所有操作都会进行回滚,除了你支付的矿工费)。点击发布按钮(SUBMIT),静静等待发布成功吧!此时打开 MetaMask 页面上图为发布中状态,下图为发布结束的状态,此时会发现我们的账户余额减少了一些,因为被用于支付发布合约的矿工费了。到这里还不清楚是否成功发布了,点击交易单进入交易详情页面,当你看到箭头1处的 Success 时就表示我们的 Token 发布成功啦!点击箭头2处的合约地址链接,进入合约详情页点击箭头处的 Token 地址链接,进入 Token 详情页至此我们的 Token 就做完啦!钱包中显示 Token我们以 MetaMask 为例演示一下,其他钱包比如 ImToken 同样的只需要将 Token 地址复制过去就能看到了。先切换到 Token 标签页点击添加 Token,输入刚才的 Token 合约地址点击添加按钮,就能在 MetaMask 上看到我们自己的 Token 了。小结在制作 Token 的整个过程中,并没有难点,只是大多数人不清楚流程,当自己实操一遍后立马就能上手。后面我们会去玩一些复杂一点的智能合约,但同样的,需要一些基本的 Solidity 编程语言的知识以及区块链相关的知识。Solidity 这门以太坊的标准编程语言之后的文章也会详细讲解,大家尽请期待~欢迎关注公众号:『比特扣』,与我一起探索区块链的世界。
2023年03月24日
4 阅读
0 评论
0 点赞
2023-03-24
如何在 Goerli 网络中获取测试 ETH
以太坊在合并前的最后一个测试网络于8月11日在Goerli上上线。Goerli testnet是以太坊主网预计下个月与Beacon链合并之前的最后一次测试运行。主网合并将使以太坊完全从工作量证明型区块链转换为权益证明型区块链,已在 9月中旬完成。对于开发以太坊相关DAPP等,需要获取 Goerli 网络中使用的测试 Ether。要在 Goerli 测试网上获取 ETH,需要准备一个 Twitter 帐户、Metamask。获取测试 ETH 的方法打开 Metamask 钱包并选择 Goerli 网络:复制 ETH 地址并发布一条包含以太坊地址的推文。打开 faucet.goerli.mudit.blog/ 并将推文的 URL 粘贴到输入框中。在输入框右侧选择 6.25 Ethers / 9 days完毕!几分钟后,6.25 Goerli 测试 ETH 将添加到 Metamask 钱包中。挖矿获取通过一个挖矿型的网页,把钱包地址输入进去,无需链接钱包,即可在线挖矿,只要页面不关闭就可以了。经测试,挖矿速度时快时慢,快的时候2分钟就能挖出零点几个测试ETH,慢的时候可能10多分才能挖出零点零几测试ETH,但是做为紧急情况时使用,完全足够。挖矿地址:goerli-faucet.pk910.de/这是一个在Goerli Testnet上运行的以太坊水龙头,这个水龙头需要一些挖矿工作来完成交换免费的testnet资金。建议不要使用代理只需输入ETH地址并开始挖矿,当你收集到足够的ETH时,停止挖矿并领取你的奖励。
2023年03月24日
7 阅读
0 评论
0 点赞
2023-03-24
推荐 7 个学习 Web3 的开源资源
持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 29 天,点击查看活动详情Web3.0 算是下一个趋势,目前还处于新的阶段并且不断变化中。它提供了开发去中心化应用程序和使用基于区块链的技术所需的工具,还将使用人工智能和机器学习来开发更出色的应用程序。本文收藏了 7 个学习 Web3.0 相关知识的开源资源。1. full-blockchain-solidity-course-py对于 Web3.0 的初学者来说,这事一个很好的资源,这个资源包括 Solidity、区块链和智能合约的知识库,从初学者到专家级的完整课程。它是用 python 编写的。资源地址:github.com/smartcontra…2. ethereumbook书是学习任何东西的最佳资源之一,该存储仓库包含 Andreas M. Antonopoulos 和 Gavin Wood 的“掌握以太坊”书籍,可以免费阅读。这是以太坊、以太坊经典、RootStock (RSK) 和其他兼容的基于 EVM 的开放区块链操作和使用的开发者指南。资源地址:github.com/ethereumboo…3. DeFi开发者路线图该存储仓库提供精选的 Web3.0 开发人员手册,其中包括精选的顶级 DApp 开发工具、资源和使用技巧,其内容涉及区块链、智能合约、DeFi、ENS、NFT、ETH2.0、开发框架(Truffle、Ganache)资源地址:github.com/OffcierCia/…4. ZeroNet如果想要一个真实的示例,那么这算是一个很好的资源。这是一个使用比特币加密和 BitTorrent 网络的去中心化网站,用 Python 编写的。资源地址:github.com/HelloZeroNe…5. Solidity实例如果是 Solidity 新手,那么这是必须了解的资源,该网站包含一些 Solidity 的基本示例。如果不知道什么是solidity,它是一种面向对象的编程语言,可以用来实现跨不同区块链平台的智能合约。资源地址:solidity-by-example.org/6. MetaMask如果使用过加密货币,那么可能已经知道 MetaMask。这个浏览器扩展使浏览支持以太坊区块链的网站成为可能,一个便捷的数字钱包插件。资源地址:github.com/MetaMask/me…7. Rabby这个开源浏览器插件为 Defi 生态系统提供了更加用户友好和安全的多链体验。资源地址:github.com/RabbyHub/Ra…
2023年03月24日
7 阅读
0 评论
0 点赞
2023-03-24
(一)区块链的共识算法:整体介绍 及 分叉 的通俗讲解
作者:林冠宏 / 指尖下的幽灵掘金:juejin.cn/user/178526…博客:www.cnblogs.com/linguanh/GitHub : github.com/af913337456…腾讯云专栏: cloud.tencent.com/developer/u…本文不做一般入门的区块链描述讲解。着重简述讲解:区块链的分叉 共识算法 BTW:本人技术书籍《区块链以太坊DApp开发实战》现已出版并可网购了,适合初中级区块链技术相关研发人员阅读。目录前言 简单过一下区块链 通俗讲解共识 共识算法 PoW 区块链分叉 硬分叉的出现 软分叉的出现 参考 前言由于最近的开发工作是与以太坊公链相关的去中心化交易所,项目两个多月之久,对区块链相关的知识内容了解了一些,故择文以记录之,但求文字通俗易懂,无纰漏。因自身求学过程中所遇坑无数,业内良文亦少之又少,深感朦胧之懂之不爽。此外,亦坚信区块链技术未来必能大放光芒,因现在多应用于虚拟货币,故人谈区块链,内心首想皆炒币相关之内容。简单过一下区块链我们一般意识形态中的 链 是铁链,由铁铸成,一环扣一环。形象地,区块链的也可以这么理解,只不过它不是由铁铸成,而是由拥有一定数据结构的块连接而成,这是一个最简单的雏形见下图通俗讲解共识所谓共识,通俗来说,就是我们大家对某种事物的理解达成一致的意思。比如说日常的开会讨论问题,又比如判断一个动物是不是猫,我们肉眼看了后觉得像猫,其满足猫的特征,那么我们认为它是猫。共识,是一种规则。继续我们的会议例子。参与会议的人,通过开会的方式来达到谈论解决问题。对比区块链中,参与挖矿的矿工通过某种共识方式(算法)来解决让自己的账本跟其他节点的账本保持一致。让账本保持一致的深入一层意思就是,让链中区块信息保持一致。为什么需要共识,不需要可不可以?当然不可以,生活中没了共识的规则,一切乱套。区块链没了共识的规则,各个节点各干各的,失去一致的意义。这两个例子的对应的关系如下:会议的人 = 挖矿的矿工 开会 = 共识方式(算法) 谈论解决问题 = 让自己的账本跟其他节点的账本保持一致 如果你对节点的概念意思不懂,请先理解为矿工,一个节点内部包含很多角色,矿工是其中之一。共识算法目前常见的在区块链中,节点们让自己的账本跟其他节点的账本保持一致的共识方式(算法)有如下几种:PoW,代表者是比特币 (BTC) 弊端: 矿池的出现,一定程度上违背了去中心化的初衷,同时也使得51%攻击成为可能,影响其安全性。 存在巨大的算力浪费,看看矿池消耗大量的电力资源,随着难度增加,挖出的不够付电费 PoS,代表者是以太坊 (ETH),从PoW过度到PoS 弊端: 破坏者对网络的攻击成本很低,拥有代币就能竞争 另外拥有代币数量大的节点获得记账权的概率会更大,会使得网络共识受少数富裕账户支配,从而失去公正性 DPoS,代表者是柚子(EOS) 弊端: 选举固定数量的见证人作为记账候选人有可能不适合于完全去中心化的场景 在网络节点很少的场景,选举的见证人的代表性也不强. PBFT 拜占庭容错,联盟链中常用 弊端: 不适合公有链,适合联盟链 下面通俗讲解下每种共识算法的概念,注意!是概念,非代码层面的详细实现。PoW它的全称是:Proof of Work 工作量证明。字面意思,就是谁做的活越多,谁话事权越大,一定层面上类似现实生活的多劳多得的概念。该例子会穿插生活事例,其他的几个讲解将不再累赘。拿比特币为例子,比特币挖矿就是通过计算符合某一个比特币区块头的哈希散列值争夺记账权。这个过程需要通过大量的计算实现,简单理解就是你进行的计算量大(工作量大),你就有大概率获得记账权,即矿工的挖出的区块并入主链。区块头,区块链中的区块的头部。你有一个饭盒,饭盒第一层,形象为动物头部,称之为头部。第一层放着米饭,米饭就是头部装载着的东西 哈希散列值,一种通过数学公式计算得出的值 哈希:数学中的散列函数 散列值: 通过哈希函数得出的值 例如加法公式:1 + 2 = 3。那么哈希公式:hash(1,2) = 结果 区块头的哈希散列值,饭盒第一层装着的是饭。那么这里的这个值就是区块头装着的东西 记账权,话事权,谁挖出的区块是有效的。 所以说。在很多个节点都在挖矿的情况下,大家都有可能挖出一个区块,随之广播到其他节点中去,那么每个节点中会根据谁先挖出为准,确认该区块,并入链中。对比现实生活,数学竞赛中,参数者 相当于矿工,一道题目,谁先做出就公布计算过程和答案,不由裁判判断,由参赛者一起验证,没问题后,宣布该题目结束,解题者等相关信息被记录到册子/数据库/网络。之后继续下一道题。回到比特币挖矿中:这道难题就是 计算出正确的哈希散列值 计算哈希散列值 随着难度系数增大,会越来越困难 计算需要耗费大量的电力资源,工作量大 一旦计算出了,就告诉其他节点 节点收到通知后,停下手上的计算工作 节点开始验证信息 信息有效,当前的块被挖出,各节点开始重新挖下一个 信息无效,各节点继续自己的手上的计算工作 成功挖出有效区块的节点获得奖励,比特币奖励 同时解出问题的情况怎么办?---① 答案见下一章节 区块链分叉区块链分叉注意私有节点不在讨论范围内,所有节点基于公有节点。分叉的情况有:硬分叉 一旦出现,最后的结果是一分为二 术语的说法:旧节点无法认可新节点产生的区块,为硬分叉 软分叉 一旦出现,最后的结果是能掰正的 术语的说法:旧节点能够认可新节点产生的区块,为软分叉 现在先回答上一章节留下的问题 --- ①, ① 的情况是软分叉的一种,当有两个或多个节点同时挖出了同区块号码的一个区块,然后它们同时广播信息出去,假设一个是A,而另一个是B,那么距离 A 比较近的节点,还没等到收到其他消息就先收到了 A 的信息,并开始确认 A 所挖出的这个区块的信息,随后加入A挖出的这个区块到自己所在的公链中去。同理 距离 B 比较近的节点,也会先处理 B 挖出的区块信息并添加入自己所在的公链中。上面文字对应于下图。距离 A 最近的是 节点1,距离 B 最近的是 节点5至此,出现了链的分叉。这是一种使用了同样共识算法,共识规则下导致的分叉,出现了这种情况,矿工是比较好自我纠正的。由于解题能力和矿工的数量成正比,因此两条链的增长速度也是不一样的,在一段时间之后,总有一条链的长度要超过另一条。当矿工发现全网有一条更长的链时,他就会抛弃他当前的链,把新的更长的链全部复制回来,在这条链的基础上继续挖矿。所有矿工都这样操作,这条链就成为了主链,分叉出来的链便会被抛弃掉。硬分叉的出现如果区块链软件的共识规则被改变,并且这种规则改变无法向前兼容,旧节点无法认可新节点产生的区块,且旧节点偏偏就是不升级,那么该分叉将导致链一分为二。分叉点后的链,往后互不影响,节点在站好派别后,也不会再互相广播区块信息。新节点和旧节点会开始在不同的区块链上运行(挖矿、交易、验证等)举个简单的例子,如果节点版本1.0 所接收的区块结构字段是10个,1年后发布节点2.0版本,2.0 兼容 1.0,但是 1.0 的不能接受 2.0 版本中多出的字段。硬分叉的过程:开发者发布新的节点代码,新的改变了区块链的共识规则且不被旧的兼容,于是节点程序出现了分叉(software fork) 区块链网络中部分节点开始运行新的节点代码,在新规则下产生的交易与区块将被旧节点拒绝,旧节点开始短暂的断开与这些发送被自己拒绝的交易与区块新节点的连接,于是整个区块链网络出现了分叉(network fork) 新节点的矿工开始基于新规则挖矿,旧的依然用旧的规则,不同的的矿工算力出现了分叉(mining fork) 最终,整个区块链出现了分叉(chain fork)。 一个实例:2017年8月1号,Bitcoin Cash(BCH)区块链成功在区块高度478559与主链分离。这一新的加密货币默认区块大小为8MB,并且可以实现区块容量的动态调整。 由于旧节点只认可小于1MB的区块,所以运行BCH客户端节点产生的区块无法向前兼容,将被旧节点拒绝,最后运行不同客户端的矿工将会长期运行在两条不同的区块链上(BTC和BCH)软分叉的出现不同的节点短时间差内挖出了同区块号的区块,也就是上面的例子 因共识规则被改变,旧节点能够识别新节点产生的区块,旧的块不能被新的接受 新节点全网算力大于50% 新节点全网算力小于等于50% 第二种的软分叉是不一定能由节点自我纠正的。万全的解决方案必须依赖人力升级节点到同版本。当 新节点全网算力大于50%,因为新节点算力大于50%,所以不论旧节点升级不升级,最长的链也一定会是全部由新节点生成的区块组成的链。而且,这条最长链最终都会是双方都认为合法的一条,原因参考上面谈到的最长链复制,因满足下面几点所以能被复制。 旧的能接收新的,在分叉点之后的区块参杂着 旧节点的区块 新节点的区块 新的不能接收旧的,但是最终及其之后总比旧的长 当 新节点全网算力小于等于50%,最终不能通过短的复制长的达到统一,结果是:分叉。原因如下。 旧节点最终会比新节点的链要长 新的总是不能接受旧的,不会去复制一条含有自己不能接受的块的链 写到这,发现内容铺开后比我想象中的要多。故目前暂时分成两章节,剩下的共识算法的介绍留到第二章。参考blog.csdn.net/chabuduoxia…blog.csdn.net/s_lisheng/a…完
2023年03月24日
7 阅读
0 评论
0 点赞
2023-03-24
基于以太坊上实现DApp的登录注册
“我总偏向将权利分散于网络。这样一来,就没任何组织能轻松获取控制。我不相信巨大的中央组织,天性使然。”——Bob Tayor, ARPANET缔造者本文原创发表于所问HT前端团队,原文地址:ht.askingdata.com/article/5af…今年年初的“三点钟区块链群”彻底激起了以加密数字货币的主的区块链浪潮,资本的驱动加深了人们对区块链技术的狂热。然而,作为区块链3.0的时代的更广的应用来临,技术如何落地也是在初期需要解决的第一道坎。所以今天就来试一下如何在以太坊上建立智能合约应用(Dapp),开发一个普通应用的该有的登录注册,以便我们第一时间尝鲜。为什么要使用区块链?作为一名标准的web开发人员,在开始一门新技术之前,需要仔细考虑一个问题就是:基于现有的业务如果用上区块链会更好吗?回答这个问题之前,你需要了解区块链是什么?优势是什么?这个问题就不在这里展开了,这是个相当大的话题,不清楚的同学可以移步到这里参考一下。《区块链-百度百科》、《区块链技术是什么?未来可能用于哪些方面?》那么区块链本质上就是一个去中心化的数据库,只不过这个数据库没有中心服务器、数据无法篡改同时一定程度上能够很好的保护数据隐私。对如今的互联网来说,听起来很具有革命性的技术。所以如果对于一款涉及到数据私密性、永久性安全性高的应用,这个确实是非常适合的。现在在金融、医疗、溯源、社交等等领域,很多公司逐渐开始试水更广泛的应用。而只靠发币炒币,这毕竟是种投机取巧的行为。以太坊入门必备基础接下来将会从零开始搭建基于以太坊web3js项目,开始阅读之前,你需要熟练前端或后台JavaScript语法,熟悉区块链思想和原理,如果能了解solidity语法更好,因为接下来我们会用到它,和js很像的一门语言。为了能够方便大家能够快速的了解,提供了下面几个资料供参考:《ethereum官网》以太坊官网。 《sails官方文档》一款后台的nodejs框架。 《 we3.js 文档1.0版本》以太坊上的前端框架,可实现与合约交互。 《solidity 文档》以太坊的智能合约语言,熟悉常用语法,和JavaScript语法类似。 了解上面的知识之后,就可以开始DAPP搭建之旅了,将从下面的路线讲解:搭建以太坊环境。 创建创世区块。 简单的挖矿、创建账户。 利用以太坊钱包查询账户信息。 编写智能合约。 web3.js与合约交互。 登录注册业务逻辑实现。 postman接口测试 项目代码可点击查看github.com/Elliottssu/…一、以太坊环境搭建如果已经有以太坊环境的同学可以跳过,接下来以mac系统为例介绍,windows也差不多。通过Homebrew来安装go-ethereumbrew tap ethereum/ethereum可以添加--devel以下命令来安装开发分支(建议用这个):brew install ethereum --devel执行geth version查看版本号,如果正常的话即安装成功。二、新建创世区块在比特币系统里,这个创世块是被写入源码,但对于以太坊而言,创世块可以是任何你喜欢的东西。你也可以把这个当成是系统的一个漏洞。但是共识算法确保其它人除非纳入你的创世块,否则是不会有效的。创世区块的目的是搭建私有链,作为链上的第一个块,如果直接运行节点的话会同步公链的数据,数据量会非常大。如果想在同一个网络中获取数据,创世区块也必须要一样。新建genesis.json文件内容如下:{ "config": , "nonce": "0x0000000000000042", "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", "difficulty": "0x100", "alloc": , "coinbase": "0x0000000000000000000000000000000000000000", "timestamp": "0x00", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "extraData": "0x00", "gasLimit": "0xffffffffffff" } 复制代码上面定义了一些如挖矿难度、以太币数量、gas消耗限制等等信息。在当前目录下执行geth init genesis.json 来初始化创世区块节点。至此,环境配置方面已经完成。我们可以通过下面这个命令在8545端口来启动节点:geth --rpc --rpccorsdomain "*" --rpcapi "personal,web3,eth,net" console三、创建账户以及挖矿首先我们需要创建第一个账户密码是12345678,执行命令:personal.newAccount('12345678')创建账户之后就可以挖矿了,注意如果有多个帐户,挖到的以太币默认都会进入第一个账户的余额里。miner.start()启动挖矿,miner.stop()停止挖矿四、利用以太坊钱包查询账户信息截止到现在,我们已经成功的启动以太坊节点,并可以通过命令来新建账户,执行挖矿来获取以太币操作。可是通过命令我们可能无法直观的感受在以太坊上账户和余额的变化。现在通过以太坊官方提供的钱包,来管理账户和余额。下载地址github.com/ethereum/mi…注意:推荐安装V0.8.10版本,可以删除已经部署的合约,方便调试,最新版的移除掉了改功能。如果有创世区块,是私有链的话,以太坊钱包会默认开启私有节点,否则默认同步公链上的数据。自己可以尝试用主账号给其他账户转账,也可以新建账号和查询账户余额。五、Solidity编写智能合约首先我们需要清楚一个问题,什么是智能合约?智能合约概念可以概括为: 一段代码 (智能合约),运行在可复制、共享的账本上的计算机程序,可以处理信息,接收、储存和发送价值。通俗的来讲就是可以在区块链上执行的代码,因为以太坊以前的区块链只能存储比特币上的交易信息,无法做其他事情。而智能合约的出现,可以在链上执行简单的业务逻辑,这也是区块链应用落地的关键。我们基础已经准备就绪,接下来就用solidity语言来写数据的增加和查询逻辑。Solidity中合约的含义就是一组代码(它的 函数 )和数据(它的 状态 ),它们位于以太坊区块链的一个特定地址上。 代码行 uint time; 声明一个类型为 uint (256位无符号整数)的状态变量,叫做 time 。 你可以认为它是数据库里的一个位置,可以通过调用管理数据库代码的函数进行查询和变更。对于以太坊来说,上述的合约就是拥有合约(owning contract)。在这种情况下,函数 set 和 get 可以用来变更或取出变量的值。1. 定义数据结构和变量这里只做一个最简单的账户体系,定义个一个用户的数据结构包含用户名、用户地址和注册时间。定义用户列表数据结构是为了存储一个用户名->用户地址的映射。//user.sol //定义用户数据结构 struct UserStruct { address userAddress; string username; uint time; uint index; } //定义用户列表数据结构 struct UserListStruct { address userAddress; uint index; } address[] public userAddresses; //所有地址集合 string[] private usernames; //所有用户名集合 mapping(address => UserStruct) private userStruct; //账户个人信息 mapping(string => UserListStruct) private userListStruct; //用户名映射地址 复制代码address[] private userAddresses; 这一行声明了一个不可以被公开访问的 address 类型的状态变量。 address 类型是一个160位的值,且不允许任何算数操作。这种类型适合存储合约地址或外部人员的密钥对。如果是关键字 public 允许则你在这个合约之外访问这个状态变量的当前值。mapping(address => UserStruct) private userStruct; mapping映射将地址映射到用户数据结构,这个可以初略理解为一个地址所对应的值有哪些。2. 判断用户名或地址是否存在//user.sol //判断用户地址是否存在 function isExitUserAddress(address _userAddress) public constant returns(bool isIndeed){ if (userAddresses.length == 0) return false; return (userAddresses[userStruct[_userAddress].index] == _userAddress); } //判断用户名是否存在 function isExitUsername(string _username) public constant returns(bool isIndeed){ if (usernames.length == 0) return false; return (keccak256(usernames[userListStruct[_username].index]) == keccak256(_username)); } 复制代码这里我们分别去判断用户名和地址是否存在,判断依据是看用户名或地址是否存在于所对应的数组。需要注意的是,在JavaScript中判断一个值是否在数组中用到的indexOf(),但是在solidity是不支持该函数。有两种方案:一种是循环集合来判断是否存在,第二种是创建的时候为每条数据加index索引,只需按索引取值。因为第一种需要遍历整个数组,当数据量非常大的时候效率不高,所以通过索引取值的方式更加快速。3. 新建数据和查询数据对于数据的插入和查询,其实就是往数组集合中添加和读取数据。//user.sol //根据用户名查找对于的address function findUserAddressByUsername(string _username) public constant returns (address userAddress) { require(isExitUsername(_username)); return userListStruct[_username].userAddress; } //创建用户信息 function createUser(address _userAddress, string _username) public returns (uint index) { require(!isExitUserAddress(_userAddress)); //如果地址已存在则不允许再创建 userAddresses.push(_userAddress); //地址集合push新地址 userStruct[_userAddress] = UserStruct(_userAddress, _username, now, userAddresses.length - 1); usernames.push(_username); //用户名集合push新用户 userListStruct[_username] = UserListStruct(_userAddress, usernames.length - 1); //用户所对应的地址集合 return userAddresses.length - 1; } //获取用户个人信息 function findUser(address _userAddress) public constant returns (address userAddresses, string username, uint time, uint index) { require(isExitUserAddress(_userAddress)); return ( userStruct[_userAddress].userAddress, userStruct[_userAddress].username, userStruct[_userAddress].time, userStruct[_userAddress].index); } 复制代码当然,除了增加和查询之外,还可对相应的数组进行修改和删除。这里的修改和删除操作其实并不是真正的更改数据,因为区块链上的数据是无法篡改的。当然除非迫不得已的话,不建议直接在链上修改和删除数据。六、web3.js与合约交互现在我们把智能合约已经写好了,可以通过js来读取和添加数据了,但在这之前需要我们部署刚才写的合约。部署合约有一种比较快捷方便的方法,就是在以太坊钱包里部署。需要注意的是,部署完成后,需要执行挖矿才能成功,因为部署合约(包括写数据),需要节点通过挖矿来确认交易。完了之后我们可以在合约列表中找到刚才部署的合约。tips: 第一次合约部署完成,如果想要推出要执行一次exit,否则合约无法保存。这时候可以点进去,执行写入数据和读取数据操作了。那么怎样才能使用代码进行操作呢?先提前看一下sails文件目录:1. 安装truffletruffle可以将solidity语言的智能合约,编译成.json格式的配置文件,可以用它来和web3.js交互。全局安装truffle,npm install -g truffle编译solidity智能合约,truffle compile执行之后会在build目录下输出编译后的结果。2. 拷贝编译后的文件中的abi的值我们编译的目的是为了拿到abi属性所对于的配置参数,手动拷贝到,nodejs的配置文件中。ps: 这种做法虽然有些傻瓜,但是项目官方推荐的合约部署与读取要简单很多。3. web3.js读取与创建合约内容先看看web3.js上是如何调用合约的:读取用methods.myMethod.call,将调用“constant”方法并在EVM中执行其智能合约方法,而不发送任何事务。注意调用不能改变智能合约状态;修改用methods.myMethod. send,将交易发送到智能合约并执行其方法。请注意,这可以改变智能合约状态。那现在就根据以太坊的合约内容,封装一些web3.js调用智能合约的类。//Contract.js const web3Util = require('./Web3Util.js') class Contract { constructor() { } //user 合约 /** * 判断用户名是否存在 */ static isExitUsername(username, cb) { web3Util.contractUser.methods.isExitUsername(username).call() .then(result => { cb(null, result) }) .catch(err => { cb(err.message) }); } /** * 根据用户名查找对于的地址 */ static findUserAddressByUsername(username, cb) { web3Util.contractUser.methods.findUserAddressByUsername(username).call() .then(result => { cb(null, result) }) .catch(err => { cb(err.message) }); } /** * 查找用户信息 */ static findUser(userAddress, cb) { web3Util.contractUser.methods.findUser(userAddress).call() .then(result => { cb(null, result) }) .catch(err => { cb(err.message) }); } /** * 创建用户信息 (发送合约需要先解锁) */ static createUser(userAddress, username, cb) { let options = { from: Web3Util.ACCOUNT_ADDRESS_MAIN, //创建账户用主账号 gas: 10000000 //最大的gas数值 } web3Util.contractUser.methods.createUser(userAddress, username).send(options) .then(result => { cb(null, result) }) .catch(err => { cb(err.message) }); } } module.exports = Contract; 复制代码上面的文件中在Web3Util.js定义了一些公共常量,如合约地址,账户地址等等。需要注意的是在使用.send()来创建合约内容的时候要给gas即小费,读取内容的时候不需要,这个是以太坊智能合约的必填项,关于gas是如何消耗的大家可以查阅相关资料了解。七、登录注册业务逻辑实现截止到目前为止,我们已经成功的将js与solidity连接在一起并且实现互动,那接下来就是实现登录和注册。登录其实就是看能否解锁用户,然后将用户的个人资料返回,注册就是调取智能合约来写入一条记录。解锁账户(只有解锁才能执行合约)方法://Web3Util.js /** * 解锁账户 * @param account 账户名 * @param password 密码 */ static unlockAccount(account, password, cb) { Web3.eth.personal.unlockAccount(account, password, 600) .then(result => { cb(null, result) }) .catch(err => { cb(err.message) }); } 复制代码登录注册执行代码://AccountController.js module.exports = { //判断用户名是否存在 isExitUsername: (req, res) => { let username = req.query.username; if (!username) return res.json(Message.errMessage('用户名不能为空')); Contract.isExitUsername(username, (err, result) => { Message.handleResult(res, err, result) }) }, //登录(用户名或地址登录) login: (req, res) => { let account = req.body.account let password = req.body.password; if (!account || !password) return res.json(Message.errMessage('用户名或密码不能为空')); if (Web3.utils.isAddress(account)) { //account is address Web3Util.unlockAccount(account, password, (err, result) => { if (err) return res.json(Message.errMessage('用户名或密码错误')); Contract.findUser(account, (err, result) => { Message.handleResult(res, err, result) }) }) } else { //account is username Contract.findUserAddressByUsername(account, (err, address) => { if (err) return res.json(Message.errMessage('用户名或密码错误')); Web3Util.unlockAccount(address, password, (err, result) => { if (err) return res.json(Message.errMessage('用户名或密码错误')); Contract.findUser(address, (err, result) => { Message.handleResult(res, err, result) }) }) }) } }, /** * 注册账户,在以太坊生成address,用户名会写在合约中 */ register: (req, res) => { let username = req.body.username let password = req.body.password; if (!username || !password) return res.json(Message.errMessage('用户名或密码不能为空')); async.waterfall([ function (callback) { //检查用户名是否存在 Contract.isExitUsername(username, (err, result) => { if (result) return res.json(Message.errMessage('用户名已存在')); callback(null, result) }) }, function (result, callback) { //创建用户 > 生成地址 Web3.eth.personal.newAccount(password).then(address => { callback(null, address) }) }, function (address, callback) { //解锁主账户并合约注册信息 Web3Util.unlockAccount(Web3Util.ACCOUNT_ADDRESS_MAIN, Web3Util.ACCOUNT__PASSWORD_MAIN, (err, result) => { if (err) return res.json(Message.errMessage(err)); Contract.createUser(address, username, (err, result) => { if (err) return res.json(Message.errMessage(err)); callback(err, result) }) }) }, ], (err, result) => { Message.handleResult(res, err, result) }) }, }; 复制代码八、postman接口测试我们已经在router中配置好了路由,接下来使用接口调试工具来测试一下,这里使用postman来测试:注意,开始测试之前需要开启以太坊节点,保证8545端口开启:geth --rpc --rpccorsdomain "*" --rpcapi "personal,web3,eth,net" console因为注册需要更改合约数据,需要挖矿来确定交易,所以为了方便调试,顺便开启挖矿:miner.start()1.注册账号因为是执行合约交易,注册完了之后会返回本次交易详情如块、消耗的gas等等。如果本次交易失败,比如再注册重复的用户名,在solidity中做了拦截,本次交易会失败,失败的标志是返回的gas是自己设置的最大值。这样我们就在链上创建了一个address,以及这个相对应的用户名和注册时间信息。2.登录账号(账号同时支持address和用户名)后续现在以及能够通过接口与智能合约交互了,我们可以稍微加个前端页面,就可以当成一个正常app了,只是数据库是区块链,是不是很酷。当然区块链上只能存储很少的数据,如果要存储视频或者图片,可以借助IPFS,(是永久的、去中心化保存和共享文件的方法,这是一种内容可寻址、版本化、点对点超媒体的分布式协议。)配合着区块链能够实现更加丰富的功能。目前的缺点在于,读取和存储交易数据比较慢,这也是目前Dapp应用无法大规模的开展的一部分原因,但这个并不会阻碍区块链技术的发展,因为它解决的是生产关系,它的思想在于去中心化来防止中央组织的滥用。在我构思这篇文章的时候,正好是Facebook创始人扎克伯格因数据泄漏丑闻在听证会被轮流质问,利用几百万用户数据来干涉总统大选。用户隐私数据一旦被攻破或滥用或商业分析推荐,后果也是非常可怕,这也是当今互联网全球化所带来的弊端。所以,如果想要区块链解决这样的问题还需要多长的路要走?
2023年03月24日
6 阅读
0 评论
0 点赞
2023-03-24
简谈什么是 Web 3.0
本文将简单介绍什么是Web 3.0,现在火热的 NFT、元宇宙(metaverse)不能称之为Web 3.0,所谓的Web 3.0是一系列协议和集成平台……它们使这些应用程序、服务和货币成为可能。Web 1.0 阅读时代:像一个单向系统,在 1980 年到 2000 年的第一个 Web 1.0 中,网页创建者编写内容,而其他用户仅获取信息并阅读。活动非常有限且静态。典型的代表就是当年的互联网大哥大雅虎以及国内的网易、新浪、搜狐这些门户网站。 Web 2.0 读与写:随着互联网的发展,在 Web 2.0 中,出现了 Facebook、YouTube、Twitter 、微博、轻博客等各种社交媒体,并成为用户之间进行交互、交换信息的一种形式。创建了以用户为中心的服务和平台,内容创建者和消费者可以在其中见面和交流。而数据主要存储集中存储。 Web 3.0 读、写、拥有:即将到来的 Web 3.0 中,人工智能、区块链、AR、VR 等新技术将模糊现实世界与数字世界的界限,人们在数字世界中花费的时间将比现在更多。随着 Web 3.0 应用程序变得更加开放和互操作,每个用户的参与和权限变得比特定平台的权限更重要。个人数字资产所有权和数据主权的重要性也在增长,比如说 NFT——创作者可以画一幅画放在链上供别人欣赏,但是创作者拥有它的所有权,只有他能够对这幅画进行一些链上的操作。而数据将以去中心化的方式连接存储。 Web 3.0 是一系列协议和支持的集成平台,使这些应用程序、服务和货币成为可能。在 Web 3.0 中,用户还可以通过使用人工智能和机器学习技术与数据进行交互。Web 3.0 是由纽约时报的 John Markoff 创建的,即所谓的第 3 代基于 Internet 的服务。Apple 的 Siri 或 Alexa 是 Web 3.0 应用程序的一个示例,它可以拥有大量信息,并将其转化为对人有用的知识和行为。Web 3.0 是一个数字世界,可以像拥有笔记本电脑或汽车一样拥有自己的数字数据,这是一个可以完全控制的地方。在以太坊的上下文中,Web 3.0 是指在区块链上运行的去中心化应用程序。Web 3.0 是区块链吗? 这是一个容易犯的错误,Web 3.0 不是区块链,是由区块链驱动的最新一代互联网应用程序和服务。这取决于机器学习和人工智能 (AI) 的使用。而 Web 3.0 的新浪潮就是元宇宙的概念的出现。元宇宙将从根本上改变我们与数字世界互动的方式。它试图创建更开放、连接和智能的网站和 Web 应用程序,重点是使用基于机器的更好地理解数据。Web 3.0 将提供一个分散的网络并基于公共区块链。在 Web 3.0 中,数据为去中心化的,不归集中的公司或政府所有,而是由所有人共享。Web 3.0 可以提高数据的安全性、隐私性和可扩展性,这在 Web 2.0 平台上是不可能的。Web 3.0 主要基于区块链技术,例如各种加密货币和不可替代的代币(NFT)。
2023年03月24日
10 阅读
0 评论
0 点赞
2023-03-24
用Golang实现以太坊代币转账
个人简介[HundredLee]2013年创业,开始从事数字货币开发工作,区块链开发工程师、iOS&Web开发者。目前担任国内知名数字货币交易平台开发商CTO。四年的技术沉淀,客户已遍布国内外,并有自主研发的JAVA高速撮合引擎。 微博 :weibo.com/hundredlee2… 邮箱 :hundred9411#gmail.com Blog : blog.sodroid.com 什么是代币?2017年区块链火爆了整个互联网金融圈,特别是ico的出现,让很多人开始认识了数字货币。我们知道以太坊(Ethereum)是目前最受欢迎的数字货币和区块链系统,而eth每个已经达到了2000+RMB。我记得刚认识以太坊的时候,是三十多一枚。那么什么是代币呢?在以太坊区块链中,我们称代币为Token,是以太坊区块链中每个人都可以任意发行的数字资产。并且它必须是遵循erc20标准的,至于erc20标准,大家可以参考这篇文章 theethereum.wiki/w/index.php… 它实际上一段智能合约代码,智能合约代码中必须要有以下的一些function 和 event。 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); }复制代码智能合约代码是运行在以太坊智能合约虚拟机中的。有兴趣的同学,可以学习一下。附上文档:solidity.readthedocs.io/en/latest/i… 我们看到上面那段类似golang中interface的代码,里面分别包含了总量、余额、转账等方法。我们今天重点讲的其实就是用golang来实现transfer、transferFrom方法。 下面进入主题。 连接以太坊RPC节点目前广泛使用的是go-ethereum,他的客户端名是geth。你可以通过编译、安装等方式把节点搭建在你的电脑或者服务器中,并开启rpc服务。本文省略这一步骤,网上有很文章供你了解。 附上github:github.com/ethereum/go… geth默认的rpc端口是8545,我使用默认端口,后面我们都用http://127.0.0.1:8545作为我们的rpc连接。 首先获取go-ethereum代码go get github.com/ethereum/go-ethereum 然后我们go-ethereum目录,如果你的golang环境没有问题,那么应该是这个路径。 cd $GOPATH/src/github.com/ethereum/go-ethereum 当你进入目录,看到代码已经完整拉取下来,那么我们就可以进行下一步了。 连接RPC节点Dont bb..我们直接上代码。 import ( "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/ethclient" ) rpcDial, err := rpc.Dial("http://127.0.0.1:8545") if err != nil { panic(err); } client := ethclient.NewClient(rpcDial)复制代码如果没有panic,那么我们已经成功连接了节点。(^__^) 创建测试账户要进行转账测试,那么我们需要两个以太坊账户。我们用golang来生成,我们知道以太坊的账户私钥是放在keystore文件中的,是一段json,并且创建的时候可以设置密码。跟比特币的wallet.dat文件是一样的意思,不见哪一样,你的资产就永远留在区块链网络中,再也无法找回。 下面我们用代码创建两个以太坊账户。 import ( "github.com/ethereum/go-ethereum/accounts/keystore" ) ks := keystore.NewKeyStore("/", keystore.StandardScryptN, keystore.StandardScryptP) address, _ := ks.NewAccount("password") account, err := ks.Export(address, "password", "password") if err != nil { panic(err) }复制代码从上面的代码我们可以看到,我创建了一个以太坊的账户,并且密码设置为password,并导出。最终account变量就是账户的私钥,是一段json文本。我们可以看看它大概长什么样。 通过address变量,我们可以获得账户的地址。比如这样 address.Address.Hex() {"address":"41e2f6a4eb0e61f627207ec4a3f7098388174368","crypto":{"cipher":"aes-128-ctr","ciphertext" :"c0b10f9a3ca83837de83d38ca95bef200170d97e818f15bbc35642b6076c4a16", "cipherparams":, "kdf":"scrypt", "kdfparams": {"dklen":32,"n":262144,"p":1,"r":8,"salt" :"05c8493a6a8518451c18ac05785e6c60507d906b130ee859e99804f0df90b63d"}, "mac" :"62f52d9c4a078765b496cf76ed50634199c509e2d6e91106e24276d51124b971"} ,"id" :"6c00339c-773b-4862-bb61-3a51a6f671ee", "version":3}复制代码反正就是这么一段json,一定要妥善保存。 生成代币文件打开 cd $GOPATH/src/github.com/ethereum/go-ethereum/cmd/abigen 你能看到main.go文件 执行 go build main.go,会在目录下生成一个main的二进制文件。 将以下的json 保存为token.abi,并放在当前目录下。 [],"payable":false,"type":"function"},,,],"name":"approve","outputs":[],"payable":false,"type":"function"},],"name":"setOwner","outputs":[],"payable":false,"type":"function"},],"payable":false,"type":"function"},,,],"name":"transferFrom","outputs":[],"payable":false,"type":"function"},],"payable":false,"type":"function"},,],"name":"push","outputs":[],"payable":false,"type":"function"},],"name":"setName","outputs":[],"payable":false,"type":"function"},],"name":"mint","outputs":[],"payable":false,"type":"function"},],"name":"balanceOf","outputs":[],"payable":false,"type":"function"},],"payable":false,"type":"function"},],"name":"setAuthority","outputs":[],"payable":false,"type":"function"},,],"name":"pull","outputs":[],"payable":false,"type":"function"},],"payable":false,"type":"function"},],"name":"burn","outputs":[],"payable":false,"type":"function"},],"payable":false,"type":"function"},,],"name":"transfer","outputs":[],"payable":false,"type":"function"},,],"payable":false,"type":"function"},,],"name":"allowance","outputs":[],"payable":false,"type":"function"},],"payable":false,"type":"constructor"},,,,,,],"name":"LogNote","type":"event"},],"name":"LogSetAuthority","type":"event"},],"name":"LogSetOwner","type":"event"},,,],"name":"Transfer","type":"event"},,,],"name":"Approval","type":"event"}]复制代码执行命令 ./main --abi token.abi --pkg main --type Token --out token.go 我们可以看到目录下生成了一个token.go文件。大功告成。 开始转账首先就把上一步生成的token.go拖入项目中。 接下来的叙述,我写在代码的注释里 import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" ) //首先导入上面生成的账户密钥(json)和密码 auth, err := bind.NewTransactor(strings.NewReader("json"), "password") //这句用的是生成的token.go里面的方法 //client变量是我们第一步连接以太坊rpc节点的时候创建的 //contractAddress 是代币地址,比如eos 的地址是0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0 //那么我们转账针对的就是账户里的eos代币 //具体看这里 https://etherscan.io/token/0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0 token, err := NewToken(common.HexToAddress("0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0"), client) if err != nil { panic(err) } //每个代币都会有相应的位数,例如eos是18位,那么我们转账的时候,需要在金额后面加18个0 decimal, err := token.Decimals(nil) if err != nil { panic(err) } //这是处理位数的代码段 tenDecimal := big.NewFloat(math.Pow(10, float64(decimal))) convertAmount, _ := new(big.Float).Mul(tenDecimal, amount).Int(&big.Int) //然后就可以转账到你需要接受的账户上了 //toAddress 是接受eos的账户地址 txs, err := token.Transfer(auth, common.HexToAddress(toAddress), convertAmount)复制代码由此,转账就大功告成了。另外,token.go里面还有很多其他的方法,有兴趣的同学,可以自行研究。 本文结束我的以太坊地址 0x67f883a42031215622e0b84c96d0E4DcA7A3ce81 哈哈哈,支持eos、omg、tnt等代币的捐赠,请我喝杯星巴克。 当然,eth也是不会拒接的。或者你可以扫码,下面是我的以太坊收款二维码。谢谢哦。 -w265
2023年03月24日
4 阅读
0 评论
0 点赞
1
2
3
...
11