heyuan 发布的文章 - 六币之门
首页
视频教程
网站导航
活动日历
关于我们
用户投稿
推荐
新闻动态
搜 索
1
融资周报 | 公开融资事件11起;加密技术公司Toposware完成500万美元融资,Polygon联创参投
107 阅读
2
六币日报 | 九只比特币ETF在6天内积累了9.5万枚BTC;贝莱德决定停止推出XRP现货ETF计划
74 阅读
3
六币日报 | 美国SEC再次推迟对灰度以太坊期货ETF做出决定;Do Kwon已出黑山监狱等待引渡
69 阅读
4
融资周报 | 公开融资事件27起;L1区块链Monad Labs完成2.25亿美元融资,Paradigm领投
68 阅读
5
【ETH钱包开发06】查询某个地址的交易记录
43 阅读
新闻动态
每日快报
一周精选
融资情况
项目投研
自治组织
数字藏品
去中心化应用
去中心化游戏
去中心化社交
去中心化金融
区块链交易所
科普知识
小白入门
用户手册
开发文档
行业报告
技术前沿
登录
搜 索
标签搜索
新闻
日报
元歌Eden
累计撰写
1,087
篇文章
累计收到
0
条评论
首页
栏目
新闻动态
每日快报
一周精选
融资情况
项目投研
自治组织
数字藏品
去中心化应用
去中心化游戏
去中心化社交
去中心化金融
区块链交易所
科普知识
小白入门
用户手册
开发文档
行业报告
技术前沿
页面
视频教程
网站导航
活动日历
关于我们
用户投稿
推荐
新闻动态
用户登录
登录
找到
1087
篇与
heyuan
相关的结果
2023-03-05
六币日报|以太坊Goerli测试网定于3月14日进行上海升级;美国参议员要求币安提供反洗钱措施相关的详细信息
今日要闻提示:美参议员要求币安提供美国用户数量、财务数据和反洗钱措施等信息,币安表示同意Windows 11已在系统中直接集成ChatGPT版新版必应彭博社:汇丰银行和Nationwide限制零售客户购买加密货币币安:没有裁员计划,拟在上半年再招聘500多人以太坊Goerli测试网计划于3月14日进行上海升级,此后3-4周进行主网升级NFT市场Few and Far完成1050万美元融资,Pantera Capital领投Silvergate股价收报5.72美元,单日跌幅达57.72%数据:今年2月NFT交易量突破20亿美元,创Terra崩盘以来新高监管消息美国法官对“SEC反对Binance.US与Voyager的拟议交易”持怀疑态度据CoinDesk报道,美国破产法院法官Michael Wiles在周四的Voyager Digital破产案法庭听证会上其对美国证券交易委员会(SEC)试图阻止Binance US收购Voyager Digital资产持严重怀疑态度。Michael Wiles表示:“这是一种奇怪的反对意见,我觉得这种反对是一种掩饰,SEC可以具体解释究竟是哪些问题,但他们真的没有,什么都没做……我需要知道具体情况。”SEC曾表示,这笔10.2亿美元的交易应该被阻止,因为Voyager的代币可能构成未注册的证券。 代表美国证券交易委员会的William Uptegrove表示,债权人没有得到足够的监管风险警告,但拒绝就VGX是否为证券采取明确立场。今日晚些时候消息,Voyager破产案周四听证会因发生骚乱被迫休庭,周五将继续审理。美参议员要求币安提供美国用户数量、财务数据和反洗钱措施等信息,币安表示同意据华尔街日报报道,三名美国参议员在给币安创始人赵长鹏和其美国最高副手Brian Shroder的信中表示:“币安及其相关实体故意逃避监管机构,将资产转移给犯罪分子和制裁逃避者,并向其客户和公众隐藏基本财务信息。”参议员要求赵长鹏和Brian Shroder提供币安自2017年以来的资产负债表副本,以及在此期间其平台上美国用户的数量。此外参议员还要求提供币安反洗钱政策和程序的文件;有关全球交易所与其美国附属公司之间关系的信息;以及披露任何涉嫌限制合规的通信,以及要求币安在 3 月 16 日之前做出回应。对此币安在一份声明中表示,关于公司的许多错误信息已经传播,但感谢参议员的要求,将提供信息以帮助他们更好地了解公司。元宇宙Windows 11已在系统中直接集成ChatGPT版新版必应微软首席产品官 Panos Panay在博文中表示,Windows 11 最新更新将新版必应(Bing)集成至任务栏搜索功能中。该功能使得用户无需打开浏览器使用新版Bing搜索,而是可以直接在任务栏的搜索框中的前端直接使用新版Bing搜索。此前1月26日消息,微软和ChatGPT创建者OpenAI扩大合作伙伴关系,拟投资数十亿美元。2月2日消息,微软宣布其旗下所有产品将全线整合ChatGPT。2月8日消息,微软发布新版必应及Edge浏览器,正式引入ChatGPT技术。NFTBlur创始人:平台重视NFT版权且不会收集用户数据,未来发展将很大程度受社区影响据CoinDesk报道,NFT市场Blur联合创始人Pacman在接受采访时表示,其真名为Tieshun Roquerre,是一名24岁的开发者和投资者。Roquerre透露,Blur代币经济学和增长战略的灵感来源于去中心化加密货币交易所Uniswap和电子商务平台淘宝。对于NFT版税,Roquerre称其立场是希望以可扩展、持久的方式最大限度地提高版权使用费,虽然有零版税的市场,但他决定通过激励交易者来远离这些市场(例如其对OpenSea的竞争策略)。对于Blur的隐私政策声明“平台收集浏览历史、电子邮件地址和工作历史等可用于创建消费者档案的信息”,Roquerre否认该平台正在收集用户数据,并表示其隐私政策“非常标准”。他补充说,它收集的数据在区块链上都是公开可见的。不过,他承诺会更新隐私政策以向用户阐明其意图。Roquerre还表示,该平台的未来将在很大程度上受到其社区的影响,该社区可以使用持有 BLUR代币总供应量39%的金库。他说:“社区可以对可用于开发功能或各种举措的财政拨款进行投票,还可以投票将财政拨款分配给新的经济设计,其中可能包括在某个时候引入平台费用以在未来产生额外的收入。”此外,报道称,Blur曾于2022年3月完成Paradigm领投的1100万美元的种子轮融资。PROOF联创:正在积极开发代币,Pass持有者将会在2025年后转换为Moonbirds Elders据NFT项目Moonbirds在社交媒体披露,PROOF联合创始人Kevin Rose和Justin Mezzell在最新直播中称,PROOF通行证将于2025年1月1日结束,届时当前持有者将成为Moonbirds Elders(这是一个暂定名称),他们将拥有“boosters(助推器)”,以在未来获得独家代币投放等活动中获得独家权限。对于潜在的代币发行,Kevin Rose表示目前正在积极开发中,他强调未来推出的代币必须要能支持PROOF生态系统。项目动态彭博社:汇丰银行和Nationwide限制零售客户购买加密货币据彭博社报道,汇丰银行(HSBC)、英国房屋抵押贷款协会(Nationwide Building Society)上周加强了对零售客户访问加密资产的限制,成为继行业丑闻和监管警告之后最新实施限制的英国银行。英国房屋抵押贷款协会通知客户,Nationwide对借记卡购买加密资产的每日限额为5,000英镑(5,965美元),而其信用卡不能再用于购买加密资产。汇丰银行表示,从上个月开始,它禁止客户通过其信用卡购买加密货币。汇丰银行在一份电子邮件声明中表示:“这是因为客户可能面临风险”。两家银行都提到了英国金融行为监管局发出的警告,该监管局多年来一直将加密货币列为高风险。两家银行加入了Banco Santander SA、Lloyds Banking Group Plc和Natwest Group Plc等机构的行列,这些机构近年来对英国客户接触加密货币施加了诸多限制。Block子公司TBD宣布推出新的比特币闪电服务提供商C=据CoinDesk报道,Jack Dorsey旗下Block专注于比特币的子公司TBD周四宣布,推出一个名为“c=(发音为“c equals”)”的比特币闪电服务提供商,这是一个新的业务实体,专注于提高闪电网络(比特币的第2层扩展解决方案)的流动性和路由效用。C=在新闻稿中表示:“连接到闪电网络需要比特币形式的流动性,C=将通过将比特币投入闪电网络并建立基础设施,以便企业和钱包可以使他们的闪电交易更加有用和可靠。”此前昨日消息,Block计划今年晚些推出自托管比特币钱包,目前正寻求合作伙伴。币安:没有裁员计划,拟在上半年再招聘500多人据Cointelegraph报道,加密交易所币安发言人表示:“截至今天,我们正在积极招聘500多个职位,目标是在上半年结束前填补职位空缺。我们没有任何裁员计划。”该发言人表示,自2023年初以来,该公司已雇用了600多名员工。在撰写本文时,币安在其职位空缺页面上列出了463个职位,职位涉及业务开发、通信、客户支持和工程等。Coinbase和Kraken高管:平台上无证券,即使被SEC认定也可通过调整对策在官司中取胜据Blockworks报道,Coinbase全球监管政策副总裁Scott Bauguess周四在华盛顿举行的米尔肯研究所未来数字资产研讨会上的小组讨论中表示:“我们很高兴我们在美国提供的产品不是证券。”Bauguess补充说,Coinbase上的代币表现得不像证券,因为缺乏股息和剩余利息;但即使所有的代币都被认定为有价证券,Coinbase也能让它发挥作用。Bauguess称:“有合理的规则,这是可以做到的。”Kraken全球政策主管Jonanthan Jachym对此表示赞同。他补充说:“在推进交易政策方面,领导人需要考虑如何调整现行法律以适应加密货币,比如信息披露、市场诚信、利益冲突规则……这不是重新创造,这些政策已经存在很长时间了,但(这项技术)有细微差别。”Ledger的全球政策主管Seth Hertlein表示,和解不能为未来的纠纷创造先例,但法庭案件可能会改变游戏规则。 Hertlein说:“Kraken的和解协议并没有在美国创造任何新的规则或法律,它对Kraken以外的任何人都没有约束力。影响范围实际上相当有限。”Kraken的Jonanthan Jachym表示,Kraken此举是战略性的,交易所期待更多关于质押的指导。尽管Kraken决定不打官司,但Jachym表示该行业已准备好战斗。Uniswap基金会成立Uniswap Bridge评估委员会,并启动评估流程Uniswap 基金会宣布成立 Uniswap Bridge 评估委员会并启动评估流程。委员会将处理 Axelar、Celer、deBridge、Hyperlane、LayerZero、Multichain、Router Protocol、Wormhole 等 8 种跨链桥与由 Celer 团队创建的 Multi-bridge implementation、Gnosis 团队创构建的 Block Header Oracle based solution、ERC-5164: 跨链执行等 3 种桥接器解决方案,重点关注 Uniswap 管理需求,并在未来几周内为 Uniswap 社区如何处理桥问题提供短期建议。此外,委员会还将就理想的长期解决方案提供指导,并就 Uniswap 社区如何在空间发展过程中继续监测和调查桥提出建议。目前,委员会成员包括 Ermyas Abebe、Jasraj “Jazzy” Bedi、Sean Casey、Ben O’Neill、Peter Robinson 与 David Hyland-Wood,仍寻求在未来几周内扩大团队。今年1月底报道,Wormhole赢得了Uniswap关于以太坊和BNB Chain间跨链桥选择的Temperature Check阶段投票。以太坊Goerli测试网计划于3月14日进行上海升级,此后3-4周进行主网升级据CoinDesk报道,以太坊开发人员计划于 3 月 14 日在 Goerli 测试网(testnet)完成上海升级(也称为 Shapella),以太坊的主网将在 Goerli 升级之后 3-4 周进行 Shapella 升级,这意味着质押的 ETH 提款将在 4 月份进行,与最初以太坊开发人员设定的三月时间表略有延迟。Celsius重新开放某些托管账户中的可分配资产的提款加密借贷平台 Celsius Network 发推称,今日某些托管账户中的可分配资产的提款将重新开放。符合条件的用户将被通知需要采取哪些步骤来促进他们的提款。破产律师:FTX资产存在“巨大缺口”,所有“A类资产”代币都有赤字据CoinDesk报道,根据FTX破产律师提交的一份文件,FTX.com的资产存在“巨大缺口”。根据最新价格计算,在FTX.com相关账户的钱包中确定了22亿美元的总资产,其中只有6.94亿美元属于流动性最强的“A类资产”,包括法币、稳定币、比特币和以太币。FTX所有属于A类资产的代币都有赤字。其他资产包括3.85亿美元的客户应收账款,以及对FTX关联公司Alameda Research和相关方的重大索赔。Alameda从FTX.com钱包和账户中净借款93亿美元。与此同时,FTX团队确定的客户应付账款为70亿美元。此外,FTX US也显示出资产缺口,与该交易所相关账户钱包中的总资产为1.91亿美元,客户应收款项为2800万美元,关联方应收款项为1.55亿美元。融资消息NFT市场Few and Far完成1050万美元融资,Pantera Capital领投据Near官方博客,NEAR生态NFT市场Few and Far宣布完成1050万美元融资,Pantera Capital领投,Cypher Capital、Huobi Ventures、Hypersphere、Metaweb、Mantis Partners、K5 Global等参投。新资金将有助于扩展平台的能力,提升用户体验,并增加Web3开发者的数量。IP所有者也将从该平台中受益。Kinship Ventures拟为其首支基金募集7500万美元,将投资Web3等领域据福布斯报道,风险投资公司Kinship Ventures正在为旗下首支基金募集7500万美元资金,该基金将专注于投资Web3、早期消费品等新兴领域。去年4月,Kinship Ventures参投了加密货币支付平台MoonPay的8700万美元融资,但Kinship Ventures未透露具体投资金额。矿业消息俄罗斯资管公司Finam将推出专注于加密挖矿公司的投资基金据Bitcoin.com报道,俄罗斯投资管理公司Finam Management正在建立一只为该国加密挖矿公司融资的封闭式共同投资基金,它将作为风险基金运营,通过一个特殊实体购买挖矿硬件,然后租赁设备。该基金将于3月在专业托管机构注册,它将向合格投资者开放,最低门槛为30万卢布(约合4000美元)。Finam首席执行官Vladislav Kochetkov解释说,该公司打算在合并租赁公司之前筹集5亿卢布(超过660万美元)。部分资金将用于购买矿机,其余部分将用于支付电费和维护基金。重要数据Silvergate股价收报5.72美元,单日跌幅达57.72%据新浪财经行情显示,加密友好银行Silvergate股价收报5.72美元,单日跌幅达57.72%,较240美元附近的盘中历史最高点(2021年12月31)已跌去约97.61%。Silvergate此前的客户Coinbase、 Tether、Circle、Paxos、 Crypto.com、Bitstamp、Cboe Digital Markets、LedgerX、Galaxy和Gemini纷纷表示他们将暂停与该银行的业务,Circle也表示正解除与其的部分服务,MicroStrategy也澄清与Silvergate的关系。数据:BUSD市值跌破100亿美元,较去年11月高点缩水近139亿美元据Coingecko数据显示,BUSD市值已跌破100亿美元关口,截至目前为9,632,022,901美元,较2022年11月时234.9亿美元高点减少138.6亿美元。数据:今年2月NFT交易量突破20亿美元,创Terra崩盘以来新高DappRadar的最新报告显示,今年2月份NFT交易量突破20亿美元,创2022年5月Terra及其UST和LUNA代币崩盘以来的新高。这在很大程度上与2月中旬Blur原生代币空投前的激励交易有关。
2023年03月05日
7 阅读
0 评论
0 点赞
2023-03-05
一周精选丨LSD热度不减;ZK赛道起势;Silvergate“雷声”滚滚,引发市场恐慌
六币News编者按:六币News精选了一周的优质内容,帮助大家利用周末时间查漏补缺,点击标题即可阅读。今日六币News 2023年2月专栏作者影响力及专栏文章热度排行榜出炉,有哪些专栏作者和热门文章上榜呢?点此查看宏观视角一览以色列Web3图景:不容小觑的Web3科技强国以色列拥有像Eli Ben Sasson、Shaffi Goldwasser、Yehuda Lindell、Aviv Zohar、Eran Tromer等知名密码学者,而且他们是MPC和ZKP等革命性技术的重要推动者。解析香港证监会20万字咨询文件:框架蓝图、机遇与挑战为更好地理解《咨询文件》,本文从框架蓝图、机遇与挑战三个方面进行解析。12张图表解读2月加密行业:NFT引领加密市场早春回暖对于加密行业而言,早春二月是一个好坏参半的月份,一方面稳定币BUSD遭受冲击,另一方面NFT市场则引领了加密市场的回暖。本轮上涨行情的推手找到了?链上分析某神秘基金动作与加密市场走势的关系神秘基金再出手,小牛顶来了吗?捕捉先机5个ve(3,3)类项目对比与现状:Velodrome、Equalizer、Thena的收入相对健康,Solidlizard和Solidly v2主要来自于代币补贴Solidly的分叉出现在了各条EVM链上,且取得了不错的流动性,它们的发展是否健康呢?一览最近完成融资的 7 个有趣的 Web3 项目进入 2023 年,哪些有趣的新项目值得我们关注?在探索和撰写本文时,我发现新项目比以前的更有趣。新项目的整体质量正在提高,高估的趋势正在降低。尽管仍然会有许多荒谬的项目,但加密行业各个子领域的整体质量正在提高。详解GameFi新范式:基于全链游戏的“Battle To Play”模型什么样的游戏模式可能会是全链游戏的新玩法呢?我们提出了Battle To Play模型,即用户与游戏机制进行博弈或用户之间的博弈玩法。一文盘点Starknet上值得关注的10个头部项目我们将探讨2023 年最有前途的以太坊第 2 层生态系统——Starknet 的十个项目。但在此之前,让我们先了解一下 Starknet 以及让它如此特别的因素!详解新公链Sui及其生态Sui 是首个完全无需许可Layer 1区块链,特点在于安全、快速。它实现了平行交易,并在交互足够简单时不需要共识而是使用更简单、快速的结算方式,因此给金融、数字商务和游戏带来了巨大的可能性。Web3那些事儿Blur创始人公布身份,原来这些Web3大佬都来自麻省理工学院MIT除了 NFT 交易平台,在公链、交易所、VC、媒体、Layer2 等 Web3 和 Crypto 的多个赛道,麻省理工学院(MIT)的毕业生和教授们均有一席之地。市场恐慌又至?仅1000个客户的Silvergate走入加密“死胡同”加密友好型银行Silvergate正遭遇一连串暴击,股价单日跌幅近60%,在监管趋严的背景下,Silvergate能否有生还机会?速览Magic Eden投资的11家Web3游戏工作室本文六币News将对Magic Eden投资的11家工作室及其游戏进行简要介绍,或许这当中就有某个“潜力股”在将来会成长为爆款。Jump Crypto如何与Oasis通过逆向攻击追回12万枚ETH的Wormhole被盗资金Jump Crypto和Oasis合作针对一份可升级的Oasis合约进行了逆攻击操作,从Wormhole黑客的金库(vaults)追回了被盗资金。Web3中的隐私究竟是什么?Web3中的隐私就像房间里的大象,它既是与去中心化、匿名和无需信任并列的最大卖点,也因为难以忍受的KYC、易于追踪的PII和外界的怀疑目光而成为最大痛点。大话NFT视频|盘点艺人们的Web3之旅,在NFT道路上是大哥还是大割?正所谓加密圈一天,人间一年,Web3的魅力,除了吸引到众多凡人纷纷入圈外,更加让不少艺人也为之著迷,进军Web3,视频跟大家一起盘点艺人们的Web3之旅!数据透析Blur交易大战:地板价较Opensea低5%,高积分用户当前预估营收为负想要获得高积分,需要投入较大资金成本,并且,在积分规则的鼓励下,地板价有下行动力,用户需要持续地、动态地管理自己的成本-预估价值差。币安推出的Bicasso大火背后,还有哪些NFT项目正展开生成式AI叙事除了Bicasso,加密市场中还有哪些聚焦生成式AI的平台?旗下元宇宙基金被关闭,Republic重金押注的虚拟土地还是门好生意吗?美国SEC监管压力下Republic将正式退出虚拟土地的投资舞台?该平台曾购入的虚拟土地如今还“香”吗,发展现状究竟如何?技术范儿超级链来临:深度解读Coinbase和Optimism联手打造的OP Stack一半是海水,一半是火焰。盘点近期ZK赛道重点融资项目:ZK-VM将如何构建Web3的未来本文六币News将通过介绍近期新出现的ZK融资项目,为大家梳理ZK赛道的关键概念和发展方向。为什么从Optimism转移资金到以太坊主网需要7天挑战期?为什么偏偏是 7 天呢?3 天?5 天不行吗?深度探讨比特币链上NFT:Ordinals 变革及比特币可扩展性对于投资者而言,一方面可以关注诸如 Ordinal Punk 等具有“创世”属性的高价值稀缺NFT的交易机会,另一方面可以关注莱特币等类似比特币网络的区块链引入Ordinals的新鲜叙事。但与此同时,也应注意短期热潮过后,投机者离场,资产价格下跌的风险。重点资讯第三届六币News 六币RTY AWARD年度评选开启投票,将于3月23日截止OpenAI宣布开放API,开发人员可将ChatGPT集成到自己的产品中美SEC主席:除比特币外所有加密货币都是证券MicroStrategy:没有由Silvergate Capital托管的资产,不会因Silvergate破产而提前偿还贷款公链项目Conflux完成1000万美元代币融资孙宇晨向Lido存入1万枚ETH,目前共质押20万ETHBitwise首席投资官:看好未来三年,加密市场将迎来前所未有的大牛市周期隐私网络Iron Fish将于3月14日上线主网,并空投94万枚主网代币Sui CTO :Aptos刻意打压Sui和Move开发者,对其感到失望以太坊核心开发者:未来Goerli测试网最终会被关闭
2023年03月05日
8 阅读
0 评论
0 点赞
2023-03-03
025:AirCoin WebUI 设计概要|《ETH原理与智能合约开发》笔记
待字闺中开发了一门区块链方面的课程:《深入浅出ETH原理与智能合约开发》,马良老师讲授。此简书文集记录我的学习笔记。课程共8节课。其中,前四课讲ETH原理,后四课讲智能合约。第八课分为三部分:Web应用架构 AirCoin WebUI 设计概要 AirCoin WebUI 实际开发演示 这篇文章是第八课第二部分的学习笔记:AirCoin WebUI 设计概要。这节课主要讲解了AirCoin Web 前端的设计概要。介绍了其中涉及到文件的作用,序列图,重点讲解了实现前端逻辑的 app.js 文件(下一篇)。1、AirCoin WebUI 设计概要空气币(AirCoin)来自于上节课的例子,它是一个基于 ERC 20 发行的代币,在那节课中只有后端的智能合约实现的逻辑,没有前端。这节课就实现它的前端逻辑。这个例子是一个官方的教学实例,马老师进行了大量的修改。WebUI 设计概要1.1 文件列表静态页面 index.html这个文件修改自 TutorialToken app.js这个文件实现了前端的逻辑,比如:读取合约的JSON文件、生成合约对象,合约实例;调用web3js、truffle-contract;批量转账等功能。 批量转账是向多个账户转账。它可以有两种方式,一种是在智能合约里实现,一种是在JS文件里实现,这节课中用的是后一种。2_deploy_contracts.js这个是合约的部署文件。 bs-config broswer-sync 配置文件前端的测试环境用了一个叫 broswer-sync 的东西,它可以动态地修改前端的参数,加快开发进度。 web3.min.js, truffle-contract.min.js这两个文件也需要更新一下。 1.2 序列图前端交互的时序图。实例中使用的 Ganashi 即代表是后端,也代表整个区块链,它是一个很方便的测试框架。前端就是上图中的webUI,它基于 TruffleContract 和 web3js 两个组件,和Ganashi 进行通信。时序图如上图,创建实例后,前端向两个智能合约发起调用,以及获得反馈。1.3 前端页面展示前端页面(我的电脑因升级导致虚拟机不能用了,这图是视频上截的)最上面是众筹的信息。总的供给量,对应账户及余额。下面是输入部分,账户,以太币,以wei为单位,汇率是8,两个按钮是买空气币,和批量转账。下面是每个账户对应的余额。展示以太币的变化情况。地址0是缺省地址,地址1是钱包地址,负责收钱。无论是谁花了以太币买空气币,都转到地址1;地址5到8演示批量转账。2、代码分析2.1 代码的目录前端的实现文件主要是在 src 文件夹。如图。另外,图中的 bs-config.json 是broswer-sync 的配置文件。目录截图(这图也是视频上截的)2.2 index.htmlindex.html局部截图上图是index.html的主要部分,加了 id 的,是需要使用 JS 更新的,后面结合 app.js 来分析。后面是一个table 表格,用来显示各个地址下的余额。再后面是加载相关的JS文件,其中 web3.min.js, truffle-contract.min.js 要用老师更新过的文件。2.3 app.js使用 vim src/js/app.js 打开文件。这个文件是本实例中最重要的JS文件,它实现了前端页面的所有逻辑。这些逻辑都包含在叫 App 的对象中。(没状态了,先放一放,下篇吧 -_-!!!)小结,这节主要介绍了AirCoin Web 前端的设计概要。不足之外,请批评指正。
2023年03月03日
9 阅读
0 评论
0 点赞
2023-03-03
以太坊(ETH)GAS详解
本文翻译自:http://ethdocs.org/en/latest/contracts-and-transactions/account-types-gas-and-transactions.html?highlight=gas#what-is-gas什么是Gas?以太坊在区块链上的的执行环境的实现称为以太坊虚拟机(EVM)。 参与网络的每个节点都运行EVM作为区块验证协议的一部分。 他们会检查正在验证的块中列出的交易,并运行由EVM中的事务触发的代码。 网络中的每个全节点执行相同的计算并存储相同的值。 显然,以太坊不是要优化计算效率。,因为它的并行处理是冗余的。在不需要可信的第三方,权威或暴力垄断的情况下,以太坊提供一种有效的方式来达成系统状态的共识。但是很明显,这不是最优的计算方式。合约执行是跨节点冗余复制的事实自然会使它们变得昂贵,这通常会产生不使用区块链进行离线计算的动机。当你运行一个去中心化应用(dapp)时,它会与区块链交互以读取和修改其状态,但是dapps通常只会放置对达成共识至关重要的业务逻辑和状态到区块链上。当由于消息或事务触发而执行合约时,每个指令都在网络的每个节点上执行。 这具有一定的成本:对于每个执行的操作都有指定的成本,以一定gas单位表示。Gas是交易发起人需要为以太坊区块链上的每项操作支付的执行费的名称。 gas这个名称的灵感来源于这种费用可以作为加密燃料,驱动智能合约的运动。 gas可以从执行代码的矿工那里购买。 由于gas单位与具有自然成本的计算单元对齐,因此gas和ether有意地解耦,而ether(以太)的价格通常是随市场波动的。 这两者是由自由市场调节的:gas的价格实际上是由矿工决定的,他们可以拒绝处理gas价格低于最低限额的交易。 你只需在你的账户中添加一定的以太币就可以获得gas。 以太坊客户端会自动为你的以太币购买gas,金额为您指定的金额,作为交易的最大支出。根据以太坊协议,在合约或交易中执行的每个计算步骤都要收取费用,以防止在以太坊网络上的恶意攻击和滥用。每笔交易都必须包含gas limit和愿意为gas支付的费用。矿工可以选择是否打包交易和收取费用。如果由交易产生的计算步骤所使用的gas总量(gas used ),包括原始消息和可能被触发的任何子消息,小于或等于gas limit,则处理该交易。如果gas总量超过gas limit,那么所有的改变都会回退,除非交易仍然有效并且矿工接受了这个费用。交易执行中未使用的所有多余的gas将以Ether返还给交易发起人。你不必担心超支,因为你只需支付消耗的gas费用。这意味着发送高于估计值gas limit的交易是有用的,也是安全的。估算交易成本交易中花费的总共的ether成本取决于2个因素:gasUsed:是交易中消耗的总共的gasgasPrice:在交易中指定一个单位gas的价格(ether)总费用 = gasUsed * gasPricegasUsedEVM中的每个操作都指定了要消耗的gas量。 gasUsed是执行所有操作的所有gas的总和。 有一个电子表格,提供了这背后的一些分析。为了估算gasUsed,这里有一个可以使用的estimateGas API,但有一些注意事项。gasPrice用户构造并签名交易时,每个用户都可以指定他们希望的任何gasPrice,它甚至可以是零。 然而,Frontier推出的以太坊客户端的默认gasPrice为0.05e12 wei。 由于矿工优化了他们的收入,如果大多数交易都是以0.05e12 wei的gas价格提交的,那么很难说服矿工接受指定较低或零的gas价格的交易。估算交易成本的例子举个例子,一个合约只是添加2个数字,EVM OPCODE ADD消耗3gas。使用默认gas价格(截至2016年1月)的大致成本为:3 * 0.05e12 = 1.5e11 wei注意:gas的最小单位为wei,1ether = 10^18wei换算成以太的话,就是0.00000015 Ether.question gas fees gas cost calculator Ethereum Gas Prices Operation Name Gas Cost Remark step 1 default amount per execution cycle stop 0 free suicide 0 free sha3 20 sload 20 get from permanent storage sstore 100 put into permanent storage balance 20 create 100 contract creation call 20 initiating a read-only call memory 1 every additional word when expanding memory txdata 5 every byte of data or code for a transaction transaction 500 base fee transaction contract creation 53000 changed in homestead from 21000
2023年03月03日
5 阅读
0 评论
0 点赞
2023-03-03
【ETH钱包开发01】创建、导出钱包
简介这篇文章主要是介绍ETH移动端(Android)钱包开发,核心功能包括创建钱包、导入钱包、钱包转账(收款)、交易查询等。关于钱包的基本概念钱包地址以0x开头的42位的哈希值 (16进制) 字符串keystore明文私钥通过加密算法加密过后的 JSON 格式的字符串, 一般以文件形式存储助记词12 (或者 15、18、21) 单词构成, 用户可以通过助记词导入钱包, 但反过来讲, 如果他人得到了你的助记词, 不需要任何密码就可以轻而易举的转移你的资产, 所以要妥善保管自己的助记词明文私钥64位的16进制哈希值字符串, 用一句话阐述明文私钥的重要性 “谁掌握了私钥, 谁就掌握了该钱包的使用权!” 同样, 如果他人得到了你的明文私钥, 不需要任何密码就可以轻而易举的转移你的资产和银行卡做个简单类比地址=银行卡号密码=银行卡密码私钥=银行卡号+银行卡密码助记词=银行卡号+银行卡密码Keystore+密码=银行卡号+银行卡密码Keystore ≠ 银行卡号私钥通过椭圆曲线签名得到公钥 ,公钥经过哈希得到钱包地址 ,整个过程单向的(不可逆 )私钥------->公钥------->钱包地址关于BIP协议这里先简单介绍一下BIP,后面再单独出一篇文章讲解。BIP协议是比特币的一个改进协议,在钱包开发中主要用到BIP32、BIP39、BIP44BIP32:定义了层级确定性钱包( Hierarchical Deterministic wallet ,简称 HD Wallet),是一个系统可以从单一个 seed 产生一树状结构储存多组 keypairs(私钥和公钥)。好处是可以方便的备份、转移到其他相容装置(因为都只需要 seed),以及分层的权限控制等。BIP39:用于生成助记词,将 seed 用方便记忆和书写的单词表示,一般由 12 个单字组成,单词列表总共有2048个单词。WordlistsBIP44:基于 BIP32 的系统,赋予树状结构中的各层特殊的意义。让同一个 seed 可以支援多币种、多帐户等。各层定义如下:m / purpose' / coin_type' / account' / change / address_indexpurporse': 固定值44', 代表是BIP44 coin_type': 这个代表的是币种, 可以兼容很多种币, 比如BTC是0', ETH是60',btc一般是 m/44'/0'/0'/0,eth一般是 m/44'/60'/0'/0 account’:账号 change’: 0表示外部链(External Chain),用户接收比特币,1表示内部链(Internal Chain),用于接收找零 address_index:钱包索引 准备工具eth钱包开发需要借助2个第三方库web3j:可以理解为eth API的java版本bitcoinj:生成支持bip32和bip44的钱包。还有其他的一些库支持bip32和bip44,比如:Nova Crypto的系列包,包含bip32,bip39,bip44,我就是使用的Nova Crypto系列包。注意:因为web3j不支持生成bip44的钱包,而市面上大多数钱包使用bip32,bip39,bip44标准结合生成,所以引用此包。在创建完钱包之后,你可以使用下面这个工具去测试助记词, 和校验助记词生成的地址、公钥、私钥等。https://iancoleman.io/bip39/创建钱包在了解BIP 后,我们开始以太坊钱包开发,创建的钱包的流程为:1、随机生成一组助记词2、生成 seed3、生成 master key4、生成 child key5、我们取第一组child key即m/44'/60'/0'/0/0 得到私钥,keystore及地址1、引用库:web3j implementation 'org.web3j:core:3.3.1-android' 创建钱包相关全家桶的那个bip32有点问题,用我这里给出的那个// implementation 'org.bitcoinj:bitcoinj-core:0.14.7' implementation 'io.github.novacrypto:BIP39:0.1.9' //用于生成助记词 implementation 'io.github.novacrypto:BIP44:0.0.3' // implementation 'io.github.novacrypto:BIP32:0.0.9' //使用这个bip32 implementation 'com.lhalcyon:bip32:1.0.0' implementation 'com.lambdaworks:scrypt:1.4.0' //加密算法 2、生成随机助记词 /** * generate a random group of mnemonics * 生成一组随机的助记词 */ public String generateMnemonics() { StringBuilder sb = new StringBuilder(); byte[] entropy = new byte[Words.TWELVE.byteLength()]; new SecureRandom().nextBytes(entropy); new MnemonicGenerator(English.INSTANCE) .createMnemonic(entropy, sb::append); return sb.toString(); } 3. 根据助记词计算出Seed,得到master key ,根据BIP44派生地址,获取KeyPair/** * generate key pair to create eth wallet_normal * 生成KeyPair , 用于创建钱包(助记词生成私钥) */ public ECKeyPair generateKeyPair(String mnemonics) { // 1. we just need eth wallet_normal for now AddressIndex addressIndex = BIP44 .m() .purpose44() .coinType(60) .account(0) .external() .address(0); // 2. calculate seed from mnemonics , then get master/root key ; Note that the bip39 passphrase we set "" for common byte[] seed = new SeedCalculator().calculateSeed(mnemonics, ""); ExtendedPrivateKey rootKey = ExtendedPrivateKey.fromSeed(seed, Bitcoin.MAIN_NET); Log.i(TAG, "mnemonics:" + mnemonics); String extendedBase58 = rootKey.extendedBase58(); Log.i(TAG, "extendedBase58:" + extendedBase58); // 3. get child private key deriving from master/root key ExtendedPrivateKey childPrivateKey = rootKey.derive(addressIndex, AddressIndex.DERIVATION); String childExtendedBase58 = childPrivateKey.extendedBase58(); Log.i(TAG, "childExtendedBase58:" + childExtendedBase58); // 4. get key pair byte[] privateKeyBytes = childPrivateKey.getKey(); ECKeyPair keyPair = ECKeyPair.create(privateKeyBytes); // we 've gotten what we need String privateKey = childPrivateKey.getPrivateKey(); String publicKey = childPrivateKey.neuter().getPublicKey(); String address = Keys.getAddress(keyPair); Log.i(TAG, "privateKey:" + privateKey); Log.i(TAG, "publicKey:" + publicKey); Log.i(TAG, "address:" + Constant.PREFIX_16 + address); return keyPair; } 这一步已经得到钱包公钥、私钥、地址了。如果需要测试助记词, 和校验助记词生成的地址, 那么可以访问这个网站 : https://iancoleman.io/bip39/4、通过keypair创建钱包 /** * 创建钱包(助记词方式) * * @param context app context 上下文 * @param password the wallet_normal password(not the bip39 password) 钱包密码(而不是BIP39的密码) * @param mnemonics 助记词 * @param walletName 钱包名称 * @return wallet_normal 钱包 */ public Flowable<HLWallet> generateWallet(Context context, String password, String mnemonics, String walletName) { Flowable<String> flowable = Flowable.just(mnemonics); return flowable .map(s -> { ECKeyPair keyPair = generateKeyPair(s); WalletFile walletFile = Wallet.createLight(password, keyPair); HLWallet hlWallet = new HLWallet(walletFile, walletName); WalletManager.shared().saveWallet(context, hlWallet); //保存钱包信息 return hlWallet; }); } 这样生成的就是符合bip32、bip39、bip44的钱包,也能和市面上包括imtoken在内的大多数钱包通用了。HLWalletpublic class HLWallet { public WalletFile walletFile; //钱包文件,包含私钥、keystore、address等信息 public String walletName; //钱包名称 @JsonIgnore public boolean isCurrent = false; public HLWallet() { } public HLWallet(WalletFile walletFile) { this.walletFile = walletFile; } public HLWallet(WalletFile walletFile, String walletName) { this.walletFile = walletFile; this.walletName = walletName; } public String getAddress(){ return Constant.PREFIX_16 + this.walletFile.getAddress(); } public String getWalletName() { return walletName; } public void setWalletName(String walletName) { this.walletName = walletName; } } 导出钱包导出私钥通过解密获得ECKeyPair通过ECKeyPair获得私钥,并转换成16进制,就是最后的私钥了。 /** * 导出私钥 * * @param password 创建钱包时的密码 * @param walletFile * @return */ public String exportPrivateKey(String password, WalletFile walletFile) { try { // ECKeyPair ecKeyPair = Wallet.decrypt(password, walletFile); //可能出现OOM ECKeyPair ecKeyPair = LWallet.decrypt(password, walletFile); String privateKey = Numeric.toHexStringNoPrefix(ecKeyPair.getPrivateKey()); return privateKey; } catch (CipherException e) { e.printStackTrace(); return "error"; } } 导出keystore /** * 导出Keystore * * @param password 创建钱包时的密码 * @param walletFile * @return */ public String exportKeystore(String password, WalletFile walletFile) { if (decrypt(password, walletFile)) { return new Gson().toJson(walletFile); } else { return "decrypt failed"; } } /** * 解密 * 如果方法没有抛出CipherException异常则表示解密成功,也就是说可以把Wallet相关信息展示给用户看 * * @param password 创建钱包时的密码 * @param walletFile * @return */ public boolean decrypt(String password, WalletFile walletFile) { try { // ECKeyPair ecKeyPair = Wallet.decrypt(password, walletFile); //可能出现OOM ECKeyPair ecKeyPair = LWallet.decrypt(password, walletFile); return true; } catch (CipherException e) { e.printStackTrace(); return false; } } 注意2点:1、在导出私钥、keystore、助记词之前都需要先验证密码是否正确,也就是调用如下这个方法,如果没有抛出异常,则把信息展示给用户看。Wallet.decrypt(password, walletFile); 2、使用web3j的这个decrypt,经常会抛出OOM异常。关于解决方案,大家查看这里。https://www.jianshu.com/p/41d4a38754a3导出助记词助记词是没有办法根据私钥或者keystore推导出来的。一般的做法是在创建钱包的时候把助记词加密后在本地存储,导出时解密。注意:使用IMToken导入私钥或者KeyStore创建的钱包,没有导出助记词的功能;如果是通过助记词创建的,就会有导出助记词的功能。而且助记词一旦备份之后,备份这个功能就会消失,也就是说从本地存储中删除。 /** * 导出助记词 * * @param password * @param hlWallet * @return */ public String exportMnemonics(String password, HLWallet hlWallet) { WalletFile walletFile = hlWallet.walletFile; if (decrypt(password, walletFile)) { return hlWallet.getMnemonic(); } else { return "decrypt failed"; } }
2023年03月03日
5 阅读
0 评论
0 点赞
2023-03-03
【ETH钱包开发02】导入钱包
简介本文主要讲解通过助记词、keystore、私钥 3种方式来导入钱包。导入钱包就是说根据输入的这3者中的一个去重新生成一个新的钱包。导入钱包的过程和创建的过程其实是差不多的。根据助记词导入钱包根据助记词导入钱包不需要原始密码,密码可以重新设置。根据用户输入的助记词,先验证助记词的合规性(格式、个数等),验证正确后,配合用户输入的密码重新生成一个新的钱包。验证助记词的合规性(格式、个数等)private boolean validateInput(String mnemonics, String password, String repassword) { // validate empty if (TextUtils.isEmpty(mnemonics) || TextUtils.isEmpty(password) || TextUtils.isEmpty(repassword)) { ScheduleCompat.snackInMain(startImportBtn, "请填写助记词和密码"); return false; } // validate password if (!TextUtils.equals(password, repassword)) { ScheduleCompat.snackInMain(startImportBtn, "密码不一致"); return false; } // validate mnemonic try { MnemonicValidator.ofWordList(English.INSTANCE).validate(mnemonics); } catch (InvalidChecksumException e) { e.printStackTrace(); ScheduleCompat.snackInMain(startImportBtn, "助记词格式不正确"); return false; } catch (InvalidWordCountException e) { e.printStackTrace(); ScheduleCompat.snackInMain(startImportBtn, "请检查单词个数"); return false; } catch (WordNotFoundException e) { e.printStackTrace(); ScheduleCompat.snackInMain(startImportBtn, "无效的助记词"); return false; } catch (UnexpectedWhiteSpaceException e) { e.printStackTrace(); ScheduleCompat.snackInMain(startImportBtn, "请检查空格与分隔符"); return false; } return true; } 助记词导入钱包/** * 助记词方式导入钱包,不需要以前的密码 * * @param context * @param password * @param mnemonics 重新设置的密码 * @param walletName * @return */ public Flowable<HLWallet> importMnemonic(Context context, String password, String mnemonics, String walletName) { Flowable<String> flowable = Flowable.just(mnemonics); return flowable .flatMap(s -> { ECKeyPair keyPair = generateKeyPair(s); WalletFile walletFile = Wallet.createLight(password, keyPair); HLWallet hlWallet = new HLWallet(walletFile, walletName); if (WalletManager.shared().isWalletExist(hlWallet.getAddress())) { return Flowable.error(new HLError(ReplyCode.walletExisted, new Throwable("Wallet existed!"))); } WalletManager.shared().saveWallet(context, hlWallet); return Flowable.just(hlWallet); }); } 根据私钥导入钱包通过私钥导入钱包其实和创建钱包的过程基本一致。因为私钥在导出的时候转换成了16进制,所以在导入私钥的时候,要把16进制转换为byte数组。/** * 私钥方式导入钱包,不需要以前的密码 * * @param context * @param privateKey * @param password 重新设置的密码 * @param walletName 钱包名称 * @return */ public Flowable<HLWallet> importPrivateKey(Context context, String privateKey, String password, String walletName) { if (privateKey.startsWith(Constant.PREFIX_16)) { privateKey = privateKey.substring(Constant.PREFIX_16.length()); } Flowable<String> flowable = Flowable.just(privateKey); return flowable.flatMap(s -> { byte[] privateBytes = Hex.decode(s); ECKeyPair ecKeyPair = ECKeyPair.create(privateBytes); WalletFile walletFile = Wallet.createLight(password, ecKeyPair); HLWallet hlWallet = new HLWallet(walletFile, walletName); if (WalletManager.shared().isWalletExist(hlWallet.getAddress())) { return Flowable.error(new HLError(ReplyCode.walletExisted, new Throwable("Wallet existed!"))); } WalletManager.shared().saveWallet(context, hlWallet); return Flowable.just(hlWallet); }); } 根据Keystore导入钱包keystore就是钱包文件,实际上就是钱包信息的json字符串。导入keystore是需要输入密码的,这个密码是你最后导出keystore时的密码。将keystore字符串变成walletFile实例再通过Wallet.decrypt(password, walletFile);解密,成功则可以导入,否则不能导入。ECKeyPair keyPair = Wallet.decrypt(password, walletFile); 这是Web3j的API,程序走到这里经常OOM!具体原因的话,我就不多说了,细节大家可以看这里https://www.jianshu.com/p/41d4a38754a3解决办法根据源码修改decrypt方法,这里我用一个已经修改好的第三方库implementation 'com.lambdaworks:scrypt:1.4.0' 修改后的解密方法public static ECKeyPair decrypt(String password, WalletFile walletFile) throws CipherException { validate(walletFile); WalletFile.Crypto crypto = walletFile.getCrypto(); byte[] mac = Numeric.hexStringToByteArray(crypto.getMac()); byte[] iv = Numeric.hexStringToByteArray(crypto.getCipherparams().getIv()); byte[] cipherText = Numeric.hexStringToByteArray(crypto.getCiphertext()); byte[] derivedKey; if (crypto.getKdfparams() instanceof WalletFile.ScryptKdfParams) { WalletFile.ScryptKdfParams scryptKdfParams = (WalletFile.ScryptKdfParams) crypto.getKdfparams(); int dklen = scryptKdfParams.getDklen(); int n = scryptKdfParams.getN(); int p = scryptKdfParams.getP(); int r = scryptKdfParams.getR(); byte[] salt = Numeric.hexStringToByteArray(scryptKdfParams.getSalt()); // derivedKey = generateDerivedScryptKey(password.getBytes(Charset.forName("UTF-8")), salt, n, r, p, dklen); derivedKey = com.lambdaworks.crypto.SCrypt.scryptN(password.getBytes(Charset.forName("UTF-8")), salt, n, r, p, dklen); } else if (crypto.getKdfparams() instanceof WalletFile.Aes128CtrKdfParams) { WalletFile.Aes128CtrKdfParams aes128CtrKdfParams = (WalletFile.Aes128CtrKdfParams) crypto.getKdfparams(); int c = aes128CtrKdfParams.getC(); String prf = aes128CtrKdfParams.getPrf(); byte[] salt = Numeric.hexStringToByteArray(aes128CtrKdfParams.getSalt()); derivedKey = generateAes128CtrDerivedKey( password.getBytes(Charset.forName("UTF-8")), salt, c, prf); } else { throw new CipherException("Unable to deserialize params: " + crypto.getKdf()); } byte[] derivedMac = generateMac(derivedKey, cipherText); if (!Arrays.equals(derivedMac, mac)) { throw new CipherException("Invalid password provided"); } byte[] encryptKey = Arrays.copyOfRange(derivedKey, 0, 16); byte[] privateKey = performCipherOperation(Cipher.DECRYPT_MODE, iv, encryptKey, cipherText); return ECKeyPair.create(privateKey); } 导入Kestore/** * 导入Keystore(推荐使用),Keystore+ 密码才能正确导入 * * @param context * @param keystore * @param password 以前的密码 * @param walletName * @return */ public Flowable<HLWallet> importKeystore(Context context, String keystore, String password, String walletName) { return Flowable.just(keystore) .flatMap(s -> { ObjectMapper objectMapper = new ObjectMapper(); WalletFile walletFile = objectMapper.readValue(keystore, WalletFile.class); //注意:这里用的是修改之后的解密方法 ECKeyPair keyPair = LWallet.decrypt(password, walletFile); HLWallet hlWallet = new HLWallet(walletFile, walletName); WalletFile generateWalletFile = Wallet.createLight(password, keyPair); if (!generateWalletFile.getAddress().equalsIgnoreCase(walletFile.getAddress())) { return Flowable.error(new HLError(ReplyCode.failure, new Throwable("address doesn't match private key"))); } if (WalletManager.shared().isWalletExist(hlWallet.getAddress())) { return Flowable.error(new HLError(ReplyCode.walletExisted, new Throwable("Wallet existed!"))); } WalletManager.shared().saveWallet(context, hlWallet); return Flowable.just(hlWallet); }); } 注意:1、导入助记词和私钥是不需要以前的密码的,而是重新输入新的密码;导入Keystore则需要以前的密码,如果密码不正确,会提示地址和私钥不匹配。2、关于备份助记词用过imtoken的同学可以看到imtoken是可以导出(备份)助记词的。这个一开始我也很困惑,后来了解到其实它实在创建钱包的时候,在app本地保存了助记词,导出只是讲数据读取出来而已。还有一点,imtoken一旦备份了助记词之后,之后就没有备份那个功能了,也就是说助记词在本地存储中删除了;而且导入钱包的时候也是没有备份助记词这个功能的。
2023年03月03日
8 阅读
0 评论
0 点赞
2023-03-03
【ETH钱包开发03】web3j转账ETH
在之前的文章中,讲解了创建、导出、导入钱包。【ETH钱包开发01】创建、导出钱包【ETH钱包开发02】导入钱包本文主要讲解以太坊转账相关的一些知识。交易分为ETH转账和ERC-20 Token转账,本篇先讲一下ETH转账。发起交易的2种方式1、解锁账户发起交易。钱包keyStore文件保存在geth节点上,用户发起交易需要解锁账户,适用于中心化的交易所。2、钱包文件离线签名发起交易。钱包keyStore文件保存在本地,用户使用密码+keystore的方式做离线交易签名来发起交易,适用于dapp,比如钱包。本文主要讲一下第二种方式,也就是钱包离线签名转账的方式。钱包文件签名的方式发起交易交易流程1、通过keystore加载转账所需的凭证Credentials2、创建一笔交易RawTransaction3、使用Credentials对象对交易签名4、发起交易/** * 发起一笔交易(自定义参数) * * @param from 发起人钱包地址 * @param to 转入的钱包地址 * @param value 转账金额,单位是wei * @param privateKey 钱包私钥 * @param gasPrice 转账费用 * @param gasLimit * @param data 备注的信息 * @throws IOException * @throws CipherException * @throws ExecutionException * @throws InterruptedException */ public EthSendTransaction transfer(String from, String to, BigInteger value, String privateKey, BigInteger gasPrice, BigInteger gasLimit, String data) throws IOException, CipherException, ExecutionException, InterruptedException { //加载转账所需的凭证,用私钥 Credentials credentials = Credentials.create(privateKey); //获取nonce,交易笔数 BigInteger nonce = getNonce(from); //创建RawTransaction交易对象 RawTransaction rawTransaction = RawTransaction.createEtherTransaction(nonce, gasPrice, gasLimit, to, value); //签名Transaction,这里要对交易做签名 byte[] signMessage = TransactionEncoder.signMessage(rawTransaction, credentials); String hexValue = Numeric.toHexString(signMessage); //发送交易 EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).sendAsync().get(); return ethSendTransaction; } /** * 获取nonce,交易笔数 * * @param from * @return * @throws ExecutionException * @throws InterruptedException */ private BigInteger getNonce(String from) throws ExecutionException, InterruptedException { EthGetTransactionCount transactionCount = web3j.ethGetTransactionCount(from, DefaultBlockParameterName.LATEST).sendAsync().get(); BigInteger nonce = transactionCount.getTransactionCount(); Log.i(TAG, "transfer nonce : " + nonce); return nonce; } 注意以下几点:1、Credentials这里,我是通过获取私钥的方式来加载Credentials//加载转账所需的凭证,用私钥 Credentials credentials = Credentials.create(privateKey); 还有另外一种方式,通过密码+钱包文件keystore方式来加载Credentials ECKeyPair ecKeyPair = LWallet.decrypt(password, walletFile); Credentials credentials = Credentials.create(ecKeyPair); 2、noncenonce是指发起交易的账户下的交易笔数,每一个账户nonce都是从0开始,当nonce为0的交易处理完之后,才会处理nonce为1的交易,并依次加1的交易才会被处理。可以通过eth_gettransactioncount 获取nonce3、gasPrice和gasLimit交易手续费由gasPrice 和gasLimit来决定,实际花费的交易手续费是gasUsed * gasPrice。所有这两个值你可以自定义,也可以使用系统参数获取当前两个值关于gas,你可以参考我之前的一篇文章。以太坊(ETH)GAS详解gasPrice和gasLimit影响的是转账的速度,如果gas过低,矿工会最后才打包你的交易。在app中,通常给定一个默认值,并且允许用户自己选择手续费。如果不需要自定义的话,还有一种方式来获取。获取以太坊网络最新一笔交易的gasPrice,转账的话,gasLimit一般设置为21000就可以了。/** * 获取当前以太坊网络中最近一笔交易的gasPrice */ public BigInteger requestCurrentGasPrice() throws Exception { EthGasPrice ethGasPrice = web3j.ethGasPrice().sendAsync().get(); return ethGasPrice.getGasPrice(); } Web3j还提供另外一种简单的方式来转账以太币,这种方式的好处是不需要管理nonce,不需要设置gasPrice和gasLimit,会自动获取最新一笔交易的gasPrice,gasLimit 为21000(转账一般设置成这个值就够用了)。 /** * 发起一笔交易 * 使用以太钱包文件发送以太币给其他人,不能设置nonce:(推荐) * * @param privateKey */ public String transfer(String toAddress, BigDecimal value, String privateKey) throws Exception { //转账者私钥 Credentials credentials = Credentials.create(privateKey); TransactionReceipt transactionReceipt = Transfer.sendFunds( web3j, credentials, toAddress, value, Convert.Unit.ETHER).sendAsync().get(); String transactionHash = transactionReceipt.getTransactionHash(); Log.i(TAG, "transfer: " + transactionHash); return transactionHash; } 如何验证交易是否成功?这个问题,我想是很多朋友所关心的吧。但是到目前为止,我还没有看到有讲解这方面的博客。之前问过一些朋友,他们说可以通过区块号、区块哈希来判断,也可以通过Receipt日志来判断。但是经过我的一番尝试,只有BlockHash是可行的,在web3j中根据blocknumber和transactionReceipt都会报空指针异常。原因大致是这样的:在发起一笔交易之后,会返回txHash,然后我们可以根据这个txHash去查询这笔交易相关的信息。但是刚发起交易的时候,由于手续费问题或者以太网络拥堵问题,会导致你的这笔交易还没有被矿工打包进区块,因此一开始是查不到的,通常需要几十秒甚至更长的时间才能获取到结果。我目前的解决方案是轮询的去刷BlockHash,一开始的时候BlockHash的值为0x00000000000,等到打包成功的时候就不再是0了。这里我使用的是rxjava的方式去轮询刷的,5s刷新一次。 /** * 开启轮询 * 根据txhash查询交易是否被打包进区块 * * @param txHash */ public static void startPolling(String txHash) { //5s刷新一次 disposable = Flowable.interval(0, 5, TimeUnit.SECONDS) .compose(ScheduleCompat.apply()) // .takeUntil(Flowable.timer(120, TimeUnit.SECONDS)) .subscribe(new Consumer<Long>() { @Override public void accept(Long num) throws Exception { Log.i(TAG, "第 : " + num + " 次轮询"); //根据blockHash来判断交易是否被打包 String blockHash = getBlockHash(txHash); boolean isSuccess = Numeric.toBigInt(blockHash).compareTo(BigInteger.valueOf(0)) != 0; if (isSuccess) { getTransactionReceipt(txHash); } } }); } /** * 停止轮询 * * @param disposable */ public static void stopPolling(Disposable disposable) { if (!disposable.isDisposed()) { disposable.dispose(); } } /** * 获取blockhash * @param txHash * @return */ public static String getBlockHash(String txHash) { Web3j web3j = Web3jFactory.build(new HttpService("https://rinkeby.infura.io/v3/xxxx")); try { EthTransaction transaction = web3j.ethGetTransactionByHash(txHash).sendAsync().get(); Transaction result = transaction.getResult(); String blockHash = result.getBlockHash(); Log.i(TAG, "getTransactionResult blockHash : " + blockHash); boolean isSuccess = Numeric.toBigInt(blockHash).compareTo(BigInteger.valueOf(0)) != 0; if (isSuccess) { getTransactionReceipt(txHash); stopPolling(disposable); } return blockHash; } catch (Exception e) { e.printStackTrace(); return ""; } } public static void getTransactionReceipt(String transactionHash) { Web3j web3j = Web3jFactory.build(new HttpService("https://rinkeby.infura.io/v3/xxxx")); try { EthGetTransactionReceipt transactionReceipt = web3j.ethGetTransactionReceipt(transactionHash).sendAsync().get(); TransactionReceipt receipt = transactionReceipt.getTransactionReceipt(); String status = receipt.getStatus(); BigInteger gasUsed = receipt.getGasUsed(); BigInteger blockNumber = receipt.getBlockNumber(); String blockHash = receipt.getBlockHash(); Log.i(TAG, "getTransactionReceipt status : " + status); Log.i(TAG, "getTransactionReceipt gasUsed : " + gasUsed); Log.i(TAG, "getTransactionReceipt blockNumber : " + blockNumber); Log.i(TAG, "getTransactionReceipt blockHash : " + blockHash); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } 正常情况下,几十秒内就可以获取到区块信息了。区块确认数区块确认数=当前区块高度-交易被打包时的区块高度。
2023年03月03日
11 阅读
0 评论
0 点赞
2023-03-03
Etherscan 上传和验证合约源码
之前发布合约的时候都没有注意到这个问题,我也是最近在Etherscan浏览器查看自己合约的时候才发现的这个问题,于是就开始解决一下呗。我看了几篇博客,我认为下面这一篇就讲的很详细。https://www.jianshu.com/p/56082f942bb3细节我就不多说了,我说说其中比较关键的一些地方,以及大家比较容易犯错的地方吧。大家先来看看,没有验证过代码的合约是这样的在Remix编译通过后,点击【Details】获取byteCode信息Details-------> ByteCode----->object注意:这里是编译刚通过的时候就要去获取这个ByteCode,而不是等到Run那里填参数之后。60806040526002805460ff1916601217905534801561001d57600080fd5b50604051610a15380380610a1583398101604090815281516020808401518385015160025460ff16600a0a84026003819055600160a060020a0333166000908152600485529586205590850180519395909491019261007e9285019061009b565b50805161009290600190602084019061009b565b50505050610136565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100dc57805160ff1916838001178555610109565b82800160010185558215610109579182015b828111156101095782518255916020019190600101906100ee565b50610115929150610119565b5090565b61013391905b80821115610115576000815560010161011f565b90565b6108d0806101456000396000f3006080604052600436106100b95763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100be578063095ea7b31461014857806318160ddd1461018057806323b872dd146101a7578063313ce567146101d157806342966c68146101fc57806370a082311461021457806379cc67901461023557806395d89b4114610259578063a9059cbb1461026e578063cae9ca5114610294578063dd62ed3e146102fd575b600080fd5b3480156100ca57600080fd5b506100d3610324565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561010d5781810151838201526020016100f5565b50505050905090810190601f16801561013a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015457600080fd5b5061016c600160a060020a03600435166024356103b2565b604080519115158252519081900360200190f35b34801561018c57600080fd5b506101956103e2565b60408051918252519081900360200190f35b3480156101b357600080fd5b5061016c600160a060020a03600435811690602435166044356103e8565b3480156101dd57600080fd5b506101e661045f565b6040805160ff9092168252519081900360200190f35b34801561020857600080fd5b5061016c600435610468565b34801561022057600080fd5b50610195600160a060020a03600435166104f2565b34801561024157600080fd5b5061016c600160a060020a0360043516602435610504565b34801561026557600080fd5b506100d36105e0565b34801561027a57600080fd5b50610292600160a060020a036004351660243561063a565b005b3480156102a057600080fd5b50604080516020600460443581810135601f810184900484028501840190955284845261016c948235600160a060020a03169460248035953695946064949201919081908401838280828437509497506106499650505050505050565b34801561030957600080fd5b50610195600160a060020a0360043581169060243516610780565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103aa5780601f1061037f576101008083540402835291602001916103aa565b820191906000526020600020905b81548152906001019060200180831161038d57829003601f168201915b505050505081565b600160a060020a033381166000908152600560209081526040808320938616835292905220819055600192915050565b60035481565b600160a060020a0380841660009081526005602090815260408083203390941683529290529081205482111561041d57600080fd5b600160a060020a038085166000908152600560209081526040808320339094168352929052208054839003905561045584848461079d565b5060019392505050565b60025460ff1681565b600160a060020a03331660009081526004602052604081205482111561048d57600080fd5b600160a060020a03331660008181526004602090815260409182902080548690039055600380548690039055815185815291517fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca59281900390910190a2506001919050565b60046020526000908152604090205481565b600160a060020a03821660009081526004602052604081205482111561052957600080fd5b600160a060020a038084166000908152600560209081526040808320339094168352929052205482111561055c57600080fd5b600160a060020a038084166000818152600460209081526040808320805488900390556005825280832033909516835293815290839020805486900390556003805486900390558251858152925191927fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5929081900390910190a250600192915050565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103aa5780601f1061037f576101008083540402835291602001916103aa565b61064533838361079d565b5050565b60008361065681856103b2565b156107785780600160a060020a0316638f4ffcb1338630876040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018085600160a060020a0316600160a060020a0316815260200184815260200183600160a060020a0316600160a060020a0316815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561070c5781810151838201526020016106f4565b50505050905090810190601f1680156107395780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b15801561075b57600080fd5b505af115801561076f573d6000803e3d6000fd5b50505050600191505b509392505050565b600560209081526000928352604080842090915290825290205481565b6000600160a060020a03831615156107b457600080fd5b600160a060020a0384166000908152600460205260409020548211156107d957600080fd5b600160a060020a038316600090815260046020526040902054828101116107ff57600080fd5b50600160a060020a038083166000818152600460209081526040808320805495891680855282852080548981039091559486905281548801909155815187815291519390950194927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600160a060020a0380841660009081526004602052604080822054928716825290205401811461089e57fe5b505050505600a165627a7a723058202fcf433c82780039ff26c6a0f0f297aee8999f119942eed8a2afb54bb1e35aa30029输入构造参数,部署合约之后得到60806040526002805460ff1916601217905534801561001d57600080fd5b50604051610a15380380610a1583398101604090815281516020808401518385015160025460ff16600a0a84026003819055600160a060020a0333166000908152600485529586205590850180519395909491019261007e9285019061009b565b50805161009290600190602084019061009b565b50505050610136565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100dc57805160ff1916838001178555610109565b82800160010185558215610109579182015b828111156101095782518255916020019190600101906100ee565b50610115929150610119565b5090565b61013391905b80821115610115576000815560010161011f565b90565b6108d0806101456000396000f3006080604052600436106100b95763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100be578063095ea7b31461014857806318160ddd1461018057806323b872dd146101a7578063313ce567146101d157806342966c68146101fc57806370a082311461021457806379cc67901461023557806395d89b4114610259578063a9059cbb1461026e578063cae9ca5114610294578063dd62ed3e146102fd575b600080fd5b3480156100ca57600080fd5b506100d3610324565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561010d5781810151838201526020016100f5565b50505050905090810190601f16801561013a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015457600080fd5b5061016c600160a060020a03600435166024356103b2565b604080519115158252519081900360200190f35b34801561018c57600080fd5b506101956103e2565b60408051918252519081900360200190f35b3480156101b357600080fd5b5061016c600160a060020a03600435811690602435166044356103e8565b3480156101dd57600080fd5b506101e661045f565b6040805160ff9092168252519081900360200190f35b34801561020857600080fd5b5061016c600435610468565b34801561022057600080fd5b50610195600160a060020a03600435166104f2565b34801561024157600080fd5b5061016c600160a060020a0360043516602435610504565b34801561026557600080fd5b506100d36105e0565b34801561027a57600080fd5b50610292600160a060020a036004351660243561063a565b005b3480156102a057600080fd5b50604080516020600460443581810135601f810184900484028501840190955284845261016c948235600160a060020a03169460248035953695946064949201919081908401838280828437509497506106499650505050505050565b34801561030957600080fd5b50610195600160a060020a0360043581169060243516610780565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103aa5780601f1061037f576101008083540402835291602001916103aa565b820191906000526020600020905b81548152906001019060200180831161038d57829003601f168201915b505050505081565b600160a060020a033381166000908152600560209081526040808320938616835292905220819055600192915050565b60035481565b600160a060020a0380841660009081526005602090815260408083203390941683529290529081205482111561041d57600080fd5b600160a060020a038085166000908152600560209081526040808320339094168352929052208054839003905561045584848461079d565b5060019392505050565b60025460ff1681565b600160a060020a03331660009081526004602052604081205482111561048d57600080fd5b600160a060020a03331660008181526004602090815260409182902080548690039055600380548690039055815185815291517fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca59281900390910190a2506001919050565b60046020526000908152604090205481565b600160a060020a03821660009081526004602052604081205482111561052957600080fd5b600160a060020a038084166000908152600560209081526040808320339094168352929052205482111561055c57600080fd5b600160a060020a038084166000818152600460209081526040808320805488900390556005825280832033909516835293815290839020805486900390556003805486900390558251858152925191927fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5929081900390910190a250600192915050565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103aa5780601f1061037f576101008083540402835291602001916103aa565b61064533838361079d565b5050565b60008361065681856103b2565b156107785780600160a060020a0316638f4ffcb1338630876040518563ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018085600160a060020a0316600160a060020a0316815260200184815260200183600160a060020a0316600160a060020a0316815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561070c5781810151838201526020016106f4565b50505050905090810190601f1680156107395780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b15801561075b57600080fd5b505af115801561076f573d6000803e3d6000fd5b50505050600191505b509392505050565b600560209081526000928352604080842090915290825290205481565b6000600160a060020a03831615156107b457600080fd5b600160a060020a0384166000908152600460205260409020548211156107d957600080fd5b600160a060020a038316600090815260046020526040902054828101116107ff57600080fd5b50600160a060020a038083166000818152600460209081526040808320805495891680855282852080548981039091559486905281548801909155815187815291519390950194927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600160a060020a0380841660009081526004602052604080822054928716825290205401811461089e57fe5b505050505600a165627a7a723058202fcf433c82780039ff26c6a0f0f297aee8999f119942eed8a2afb54bb1e35aa300290000000000000000000000000000000000000000000000000000000000000834000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000074d79546f6b656e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024d54000000000000000000000000000000000000000000000000000000000000注意:添加构造参数,部署和鱼成功之后与初始的byteCode比较发现两者就多了后面一段字节数据:0000000000000000000000000000000000000000000000000000000000000834000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000074d79546f6b656e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024d54000000000000000000000000000000000000000000000000000000000000这一段字节数据就是我们的构造参数的byteCode我就在这里犯过错,之前一直没找到构造参数的byteCode,大家务必按照步骤来,不然后面通不过。盗图借上面这篇文章的上传源码的图说明几点。第一:上面获取到的构造参数的byteCode复制到最下面的那个框中就行(切记按照步骤,我就踩过坑)第二:编译版本不是指你solidity合约代码中的版本,而是如图所示的这个(这里也踩过坑)验证成功之后的页面大概是这样的到此,恭喜你已经成功的上传和验证通过你的合约源码了!
2023年03月03日
8 阅读
0 评论
0 点赞
2023-03-03
【ETH钱包开发04】web3j转账ERC-20 Token
在上一篇文章中讲解了ETH转账,这一篇讲一下ERC-20 Token转账。【ETH钱包开发03】web3j转账ETHERC-20 Token转账的2种方式1、直接用web3j的API2、java/Android调用合约的transfer方法不管用哪种方式来转账,你都需要先写一个solidity智能合约文件来创建ERC-20 Token,然后部署合约,最后才是通过客户端来调用。web3j API转账ERC-20 Token/** * ERC-20Token交易 * * @param from * @param to * @param value * @param privateKey * @param data 附加信息需要转换成16进制数 * @return * @throws Exception */ public EthSendTransaction transferERC20Token(String from, String to, BigInteger value, String privateKey, String contractAddress) throws Exception { //加载转账所需的凭证,用私钥 Credentials credentials = Credentials.create(privateKey); //获取nonce,交易笔数 BigInteger nonce = getNonce(from); //get gasPrice BigInteger gasPrice = requestCurrentGasPrice(); BigInteger gasLimit = Contract.GAS_LIMIT; //创建RawTransaction交易对象 Function function = new Function( "transfer", Arrays.asList(new Address(to), new Uint256(value)), Arrays.asList(new TypeReference<Type>() { })); String encodedFunction = FunctionEncoder.encode(function); RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, gasPrice, gasLimit, contractAddress, encodedFunction); //签名Transaction,这里要对交易做签名 byte[] signMessage = TransactionEncoder.signMessage(rawTransaction, credentials); String hexValue = Numeric.toHexString(signMessage); //发送交易 EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).sendAsync().get(); return ethSendTransaction; } /** * 获取nonce,交易笔数 * * @param from * @return * @throws ExecutionException * @throws InterruptedException */ private BigInteger getNonce(String from) throws ExecutionException, InterruptedException { EthGetTransactionCount transactionCount = web3j.ethGetTransactionCount(from, DefaultBlockParameterName.LATEST).sendAsync().get(); BigInteger nonce = transactionCount.getTransactionCount(); Log.i(TAG, "transfer nonce : " + nonce); return nonce; } 注意:erc-20 token转账和eth转账的区别如下:1、erc-20 token创建交易对象用的是这个方法createTransaction2、erc-20 token需要构建Function,它其实对应的就是erc-20 token合约中的那些方法。它的第一个参数就是ERC20中那几个方法的名称,第二个参数的话就是对应合约方法中的参数,第三个参数是和第二个参数对应的,按照我那样就行了。转账的话就是transfer,我们从合约的transfer可以看到第一个参数是收款地址,第二个参数是金额,所以Function这里对应起来就好。 //创建Function对象 Function function = new Function( "transfer", Arrays.asList(new Address(to), new Uint256(value)), Arrays.asList(new TypeReference<Type>() { })); String encodedFunction = FunctionEncoder.encode(function); // 如下为 ERC20 Token 标准接口:----------- // ERC20 Token Standard Interface // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md // ---------------------------------------------------------------------------- contract ERC20 { function name() constant returns (string name) function symbol() constant returns (string symbol) function decimals() constant returns (uint8 decimals) 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); } java/Android调用合约的transfer方法这种方法不需要使用web3j封装的方法,而是直接调用solidity合约的方法。步骤1、web3j加载一个已经部署的合约2、验证合约是否加载成功isValid3、如何加载合约成功,则调用合约的transfer方法 /** * ERC-20Token交易(调用solidity合约方式) 推荐使用 * * @param contractAddress 合约地址 * @param to 收款地址 * @param value 转账金额 * @param privateKey 私钥 * @throws ExecutionException * @throws InterruptedException */ public void transferERC20Token(String contractAddress, String to, BigInteger value, String privateKey) throws ExecutionException, InterruptedException { //加载转账所需的凭证,用私钥 Credentials credentials = Credentials.create(privateKey); TokenERC20 contract = TokenERC20.load( contractAddress, web3j, credentials, Contract.GAS_PRICE, Contract.GAS_LIMIT); TransactionReceipt transactionReceipt = contract.transfer(to, value).sendAsync().get(); String transactionHash = transactionReceipt.getTransactionHash(); Log.i(TAG, "transferERC20Token transactionHash : " + transactionHash); } 注意:1、这里的TokenERC20是根据solidity智能合约生成的对应的Java类,用于java/Android和智能合约交互的,如果你对这里不太清楚,不妨看看我之前的一篇文章。以太坊Web3j命令行生成Java版本的智能合约2、如果加载合约失败,可能的一个原因是合约对应的Java类中的BINARY的值不对,这个值是你部署合约成功之后的bytecode,你最好检查对比一下。我发送一笔交易,可以通过这个地址查询https://rinkeby.etherscan.io/tx/0x05bd947e73068badbd9937854169f020980795da8a8182a67e9c2c1888f1874d
2023年03月03日
5 阅读
0 评论
0 点赞
2023-03-03
【ETH钱包开发05】web3j查询ERC-20 Token余额
往期回顾【ETH钱包开发01】创建、导出钱包【ETH钱包开发02】导入钱包【ETH钱包开发03】web3j转账ETH【ETH钱包开发04】web3j转账ERC-20 Token查询eth余额比较简单,这样web3j.ethGetBalance就可以了。但是之前很多朋友在问查询ERC-20Token余额该怎么办?今天就跟大家讲讲常见的几种办法。获取ERC-20Token余额需要2个参数,要查询的地址和ERC-20Token的合约地址。方案一:通过调用合约的方法来查询// 如下为 ERC20 Token 标准接口:----------- // ERC20 Token Standard Interface // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md // ---------------------------------------------------------------------------- contract ERC20 { function name() constant returns (string name) function symbol() constant returns (string symbol) function decimals() constant returns (uint8 decimals) 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); } 其实ERC-20相关的很多信息都可以通过上诉的方法来查询。加载合约load 验证合约是否可用isValid 调用合约查询余额的方法balanceOf /** * 查询erc-20 token 余额 * * @param address 要查询的地址 * @param contractAddress erc-20合约地址 * @throws Exception */ public String getERC20Balance(String address, String contractAddress) throws Exception { //加载合约 TokenERC20 contract = TokenERC20.load( contractAddress, web3j, credentials, Contract.GAS_PRICE, Contract.GAS_LIMIT); BigInteger balanceOf = contract.balanceOf(address).sendAsync().get(); String balance = toDecimal(18, balanceOf); Log.i(TAG, "getERC20Balance : " + balanceOf); Log.i(TAG, "getERC20Balance : " + balance); return balance; } public String toDecimal(int decimal, BigInteger integer) { StringBuffer sbf = new StringBuffer("1"); for (int i = 0; i < decimal; i++) { sbf.append("0"); } String balance = new BigDecimal(integer).divide(new BigDecimal(sbf.toString()), 18, BigDecimal.ROUND_DOWN).toPlainString(); return balance; } 注意:1、这里关键在于加载合约是否成功,你需要调用isValid来验证结果,返回true则表示加载成功,则可以继续后续操作,否则就需要检查加载的过程是否出错了。2、decimal 是合约创建时指定的精度方案二:web3j封装的API /** * 获取ERC-20 token指定地址余额 * * @param address 查询地址 * @param contractAddress 合约地址 * @return * @throws ExecutionException * @throws InterruptedException */ public String getERC20Balance(String address, String contractAddress) throws ExecutionException, InterruptedException { Function function = new Function("balanceOf", Arrays.asList(new Address(address)), Arrays.asList(new TypeReference<Address>() { })); String encode = FunctionEncoder.encode(function); Log.i(TAG, "getERC20Balance encode : " + encode); Transaction ethCallTransaction = Transaction.createEthCallTransaction(address, contractAddress, encode); EthCall ethCall = web3j.ethCall(ethCallTransaction, DefaultBlockParameterName.LATEST).sendAsync().get(); String value = ethCall.getResult(); Log.i(TAG, "getERC20Balance balance : " + value); return value; } 这种方案我查了一下,API确实是这样的,网上也有不少人使用,但是返回结果却是0x这样的,我暂时还不能理解,有了解的朋友可以告诉我一下。方案三:根据etherscan API接口来查询https://etherscan.io/apis#tokensetherscan 其实提供了很多API来查询交易、账号等信息,你只需要拼接URL,请求数据,返回json解析就好了。比如,查询ERC20-Token指定账号的余额,可以通过下面这个接口来完成。https://etherscan.io/apishttps://api.etherscan.io/api?module=account&action=tokenbalance&contractaddress=0x57d90b64a1a57749b0f932f1a3395792e12e7055&address=0xe04f27eb70e025b78871a2ad7eabe85e61212761&tag=latest&apikey=YourApiKeyToken参数详解module : 固定值account action : 固定值tokenbalance contractaddress : erc-20token的合约地址 address : 要查询的账户的地址 tag : 固定值latest apikey : apikey 是在etherscan调用那些接口都需要用到的一个参数,它是需要你去申请的,注册账号之后就能得到。每个账户最多持有 3 个 token, 请求 API service 服务, 仅需其中一个即可。
2023年03月03日
7 阅读
0 评论
0 点赞
1
...
91
92
93
...
109