原文转载自《刘越的科技博客》https://v3u。cn/a_id_219不得不承认,大多数人不拥有或从未拥有过加密货币。是的,Web3.0、加密货币、区块链,对于大多数互联网用户来说,其实都是过于轻浮的词汇。如果你是为了暴利投机而研究区块链和加密货币,你可能会感到失望,因为盐到处都是咸的;而如果你是为了甩掉知识而学习区块链,那你几乎肯定能满足,因为无知绝不是编程世界的常态。加密货币对支付系统的主要好处之一是去中心化,这意味着它由许多团队或团体而不是单一的中央机构控制和管理。这里不存在黑箱操作,这为系统带来了透明度。加密货币的另一个好处是它是一个点对点系统,因为它可以发送给世界上任何人,免除了微信、支付宝等第三方支付寡头的干预,这使得它们成本低廉。有效的。这一次,让我们将加密货币支付添加到支付系统中。通过Vue3.0+Tornado6的前后端分离体系,我们可以看到区块链支持的中心化支付逻辑的风格。前期准备首先,我们当然需要一个加密货币钱包。与MetaMask钱包系统集成逻辑可参考上一篇文章:青山不识,毕竟东流,集成Web3.0身份钱包MetaMask以太坊一键登录(Tornado6+Vue.js3)。之后,我们需要为接下来的支付行为获取一些“测试加密货币”。拿测试币的网站叫水龙头,测试币叫水,所以拿测试币的过程也叫引水。下面以Rinkeby的测试币收藏为例来说明一下这个过程。其他测试网的测试币收集方式类似。如果你愿意,你可以从几个测试网收集一些水。第一步,打开钱包插件,选择一个钱包,点击设置:然后,选择高级,然后启用测试网络:然后,将网络切换到Rinkeby测试网络,就可以看到另外三个比如网络测试网中的Ropsten、Kovan和Goerli。四个测试网络各有特点。Ropsten采用POW机制,可自行搭建节点挖测试币,但稳定性较差,偶尔会出现回滚区块的情况。很多实验测试,比如“zoneBlockBlockingAttack”实验都会放到这个测试网络上进行测试;Kovan、Rinkeby和Goerli使用POA机制,这些测试网络无法通过挖矿获得测试币,只能通过水龙头收集.下面以Rinkeby为例说明一下采集流程,Kovan和Goerli类似,但是采集条件更严格,大家可以根据需要采集,切换到Rinkeby测试网后,访问水龙头网站:https:///faucets.chain.link/ri...通过钱包链接登录,然后在claimform中填写钱包地址领取0.1eth币:收到交易确认后查看钱包余额:此时,准备工作完成。在钱包支付签名前端的Vue3.0项目中安装区块链模块和异步请求模块:npminstall--saveethersnpminstall--saveaxios然后在组件中导入区块链模块:import{ethers}from'醚';以及对axios的简单封装:constmyaxios=function(url,type,data={}){returnnewPromise((resolve)=>{//判断if(type==="get"||type==="delete"){axios({method:type,url:url,params:data}).then((result)=>{resolve(result.data);});}else{axios({method:type,url:url,data:qs.stringify(data)}).then((result)=>{resolve(result.data);});}});}constapp=createApp(App)app.config。globalProperties.myaxios=myaxios;接下来,当页面首次加载时,我们要检查用户是否已将他们的钱包连接到该站点。为此,我们需要使用eth\_accounts方法获取用户的帐户。如果没有返回账户,则表示用户未连接:checkIfWalletConnected:function(){window.ethereum.request({method:'eth_accounts'}).then(function(accounts){if(accounts.length>0){console.log(accounts[0]);}else{alert("应用未连接钱包");}});然后,在初始化方法中检查当前用户:created(){this.checkIfWalletConnected();如果用户钱包链接没问题,那么构建支付表单:点击支付这里,用户点击支付按钮后,进入签名逻辑:create_sign:function(){varprovider=newethers.providers.Web3Provider(web3.currentProvider);//获取签名对象varsigner=provider.getSigner();//时间戳varrightnow=(Date.now()/1000).toFixed(0);varsortanow=rightnow-(rightnow%600);//生成签名signer.signMessage("交易在“+sortanow+”处使用“+document.domain+”用于“+this.amount,this.accountaddress,”test”).then((signature)=>{this.check_sign(signature);});}这里通过Web3Provider获取签名实例,然后根据时间戳+域名+支付金额生成签名,生成签名后立即调用check\_sign方法向后台发起异步请求进行签名校验:check_sign:function(signature){this.myaxios(this.weburl+"/sign/","post",{"signature":signature,"accountaddress":this.accountaddress,"amount":this.amount}).then(data=>{if(data.errcode==0){this.makePaymentRequest(data.data.selleraddress,data.data.amount);}});}这里将签名和钱包地址发送到后端。客户端和钱包请求,请求的数据很容易被拦截和篡改,所以签名环节必不可少:后端验证和交易创建重新需要web3模块的支持:pip3installweb3然后创建验证方法:fromweb3.autoimportw3#反编译方法frometh_account.messagesimportdefunct_hash_messageimporttimeclassCheckSign(BaseHandler):asyncdefpost(self):signature=self.get_argument("signature",None)accountaddress=self.get_argument("accountaddress",None)amount=self.get_argument("amount",None)selleraddress="0x95f57Bf3837325FE99a611EFA0C7b"#Get当前域名domain=self.request.hostif":"indomain:domain=domain[0:domain.index(":")]#timestampnow=int(time.time())sortanow=now-now%600#生成签名message="Tradewith{}at{}for{}".format(domain,sortanow,amount)print(message)#反编译message_hash=defunct_hash_message(text=message)#获取签名对象signer=w3.eth.account.recoverHash(message_hash,signature=signature)print(accountaddress,signer)如果accountaddress==signer.lower():res={"errcode":0,"msg":"ok","data":{"selleraddress":selleraddress,"amount":str(w3.toWei(amount,'ether'))}}else:res={"errcode":1,"msg":"failed"}self.finish(res)这里后台使用同样的算法验证签名,如果验证通过,后台会返回商户的walletAddress,即用户转账的钱包地址。同时,支付金额会通过w3.toWei方法进行转换。以太坊的最小单位是wei,1以太坊相当于10的wei的8次方。通常,大家也使用Gwei作为Show单元。比较常用的有eth、Gwei和wei。但为了统一标准,支付表汇总了eth的最大单位,所以通过toWei方法将最大单位换算成最小单位,即0.001eth=100000000000000wei。注意转换后需要以字符串的形式返回给前端。然后后台返回商户钱包地址和转换后的支付金额给前台。创建一个事务并返回到前端。签名验证通过后,前端获取支付钱包地址和金额,立即通过钱包创建支付:makePaymentRequest:function(sellerAddress,amount){:[{from:this.accountaddress,to:sellerAddress,value:amount}]}).then(response=>{console.log("交易号:"+response);varorderid=response;}).catch(错误=>{console.log(错误);});}通过eth\_sendTransaction方法发起交易。当用户同意支付请求时,会返回本次交易的TransactionHash,即交易哈希号:确认支付交易后,得到TransactionHash:交易号:0xe937c66e337322cf3b83788b495af2da35ff9635aaaa20f156c74c7f7fddad26实际上,每笔支付交易都会产生另外一个“gas费””,而交易gas费将归属区跨链中挖出交易区块的矿工所有。矿工在挖矿时,需要决定将哪些交易放入区块,可以随机选择交易,也可以不包含任何交易。为了鼓励矿工将你的交易放入区块,你必须相应地支付一部分“小费”。支付查询支付确认后,我们可以使用Rinkeby网站查询这笔交易,输入交易哈希号:https://rinkeby.etherscan.io/...:当然,让用户自己在“faucet”查询支付结果显然不是很讲究。后台要记录交易哈希号,查询交易明细。这里我们需要一个“链上”服务来将我们的后端连接到区块链网络。访问https://infura.io/Infura是一种IaaS产品,旨在降低访问以太坊数据的障碍。对于开发人员来说,Infura是一个平台,可以让你的dApp快速访问以太坊,而无需在本地运行以太坊节点。Infura的背后是一个负载均衡的API节点集群。EthereumInfura有一系列的开发工具包。注册后,创建链接项:然后,复制Rinkeby节点链接:接下来,创建订单查询脚本checkorder.py:fromweb3importWeb3w3=Web3(Web3.HTTPProvider("https://rinkeby.infura.io/v3/32ff12c27a9c485db9a7b61b0a7f3f61"))print(w3.isConnected())print(w3.eth.getTransactionReceipt("0xe937c66e337322cf3b83788b495af2da35ff9635aaaa20f156c74c7f7fddad26"))Oncethe"on-chain"issuccessful,youcanquerythetransactiondetailsaccordingtothetransactionhashnumber,andthesystemreturns:TrueDictAttribute({'blockHash':HexBytes('0x4ede42c4bd15c7ce1736523ae1f84284c7bbdc17388cfbae0df2897bf19f287c'),'blockNumber':11098045,'contractAddress':None,'cumulativeGasUsed':13409523,'effectiveGasPrice':1500000017,'from':'0x3B14DDBA7FFF887ED3CCF01FCA0B84501FD7A7A711','GASUSE':21000,'logs':[],'logsbloom':hexbytes('0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000来00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'),'status':1,'to':'0x95f57Bf3837325FE99a611EFacff6b1d70C7731A','transactionHash':HexBytes('0xe937c66e337322cf3b83788b495af2da35ff9635aaaa20f156c74c7f7fddad26'),'transactionIndex':16,'type':'0x2'})至此,完成的加密货币支付逻辑完成,大致流程如下:1.应用会加载并自动检查Metamask钱包是否已连接。如果没有,会提示用户安装钱包插件并链接。2、交易加签名操作。3.后台校验签名,返回商户钱包地址和兑换金额。4.钱包创建交易。5.用户审核并确认付款。6.用户确认交易,生成交易号,用户和应用均收到支付确认。退款不幸的是,用户在将加密货币发送到钱包地址时必须非常小心,如果有人将加密货币发送到任何错误的地址,用户将无法取消交易或提出任何投诉以获得退款,是的,交易就是交易,交易行为写入区块后,不可撤销。但这并不意味着用户会与平台商户产生纠纷。如果沟通后达成退款协议,也可以直接从后台转入加密货币:fromweb3importWeb3importosw3=Web3(Web3.HTTPProvider("https://rinkeby.infura.io/v3/32ff12c27a9c485db9a7b61b0a7f3f61"))print(w3.isConnected())address1=w3.toChecksumAddress('selleraddress')address2=w3.toChecksumAddress('accountaddress')private_key=os.getenv('PRIVATE_KEY')#在这种情况下,随机数是账户上的交易量nonce=w3.eth.getTransactionCount(address1)#设置交易tx={'nonce':nonce,"to":address2,'value':w3.toWei("0.0001","ether"),"gas":21000,"gasPrice":w3.toWei(40,'gwei'),}signed_tx=w3.eth.account.signTransaction(tx,private_key)tx_hash=w3.sendRawTransaction(signed_tx.rawTransaction)这里商户只需要将钱包私钥导入环境变量,然后创建交易并用私钥签名,最后确认交易,获取交易哈希数。结语毫无疑问,加密货币会损害传统行业部分既得利益者的利益,但不可否认的是,加密货币是21世纪的晴天霹雳,就像史前时代遗留下来的恐龙,大戈壁中的恐龙一株枝叶稀疏的胡杨,一株在兵马俑中搏动的躯体,一株尚有体温的躯体,一株在死寂的山谷中不知从哪里响起的响亮的钟声。所谓衣不如新,人不如旧。不入春园,何知春色?所谓技术的本质就是最大限度的创新,你同意吗?原文转载自《刘越的技术博客》https://v3u.cn/a_id_219