前端请求智能合约的思路

这篇具有很好参考价值的文章主要介绍了前端请求智能合约的思路。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

从工作分工上来看,前端工程师完全可以把智能合约看做是一个后端工程师给你的接口,毕竟solidty的主要工作也是处理和返回数据的,和普通的后端工作内容相差不大,只不过代码是部署在区块链上的。

因为代码是部署在区块链上的,所以在发送请求时会与传统的请求有所不同,但本质是一样的,接下来我们要搞清楚以下三点,就能明白它的本质为什么是一样的:

1.什么是abi,我们为什么要用到它
2.为什么要借助第三方包,而不是直接请求服务器,它都有哪些作用
3.请求智能合约的原理是什么,区块是如何执行的

先看代码,因为我对ether比较熟悉,这里用ether做演示:

//区块链本质是由多个服务器跑相同的程序,存储相同的数据,然后不停地相互同步来形成的信任网络
//我们只需要链接其中一个,然后请求这个服务器即可,至于数据同步的事情不用我们处理

//provider我们称之为节点提供者(每个组成区块的服务器我们称之为节点),存储节点信息和地址信息
//我这里模拟的是DAPP的流程,节点和用户的相关信息存在window.ethereum中,可以直接获取
let provider = new ethers.providers.Web3Provider(window.ethereum)
//signer(签名者),该信息存在节点提供者中并自动与节点关联
let signer = provider.getSigner();
//这里将合约地址,abi,还有签名者之间做关联,生成一个合约对象,之后就可以调用合约对象的方法了
let contract= new ethers.Contract('合约地址', erc20abi, signer);
//这里调用了合约代币的转账方法
// ethers.utils.parseEther()是ether.js工具包中的一个方法,可以将数字字符串乘上10**16,没有精度损耗
let data = await contract.transfer("收币地址", ethers.utils.parseEther("1"))
			.catch(function(err) {
							console.log(err)
				})
//data是本次调用生成的链上数据,不是代码执行完后的返回值
console.log(data)
//监听data中的交易hash,来获取交易结果
let data2=await	provider.waitForTransaction(data.hash);
console.log(data2)

data返回值:

{
    "hash": "0xe632c016cea540b54ccde8343378e615174040fbaae68fce44ab1ea44a89a531",
    "type": 0,
    "accessList": null,
    "blockHash": null,
    "blockNumber": null,
    "transactionIndex": null,
    "confirmations": 0,
    "from": "0x173f8Ce8356dD214813f4874C316739F560D8022",
    "gasPrice": {
        "type": "BigNumber",
        "hex": "0x1ff973cafa8000"
    },
    "gasLimit": {
        "type": "BigNumber",
        "hex": "0x760e"
    },
    "to": "0x2c4eb3c76D7115E210Fadf3cBFe8E0a3d5b8448F",
    "value": {
        "type": "BigNumber",
        "hex": "0x00"
    },
    "nonce": 207,
    "data": "0xa9059cbb000000000000000000000000173f8ce8356dd214813f4874c316739f560d80220000000000000000000000000000000000000000000000000de0b6b3a7640000",
    "r": "0xd8c09aab22974fc057010152929fcb4b134a431c707c2f212f619f18297eb485",
    "s": "0x69f6e8d9f3581625797bc20cfdd2951ef225e5f24366d8f4128e8e6fdfd70316",
    "v": 2093,
    "creates": null,
    "chainId": 1029
}

data2返回值:

{
    "to": "0x2c4eb3c76D7115E210Fadf3cBFe8E0a3d5b8448F",
    "from": "0x173f8Ce8356dD214813f4874C316739F560D8022",
    "contractAddress": null,
    "transactionIndex": 0,
    "gasUsed": {
        "type": "BigNumber",
        "hex": "0x6a09"
    },
    "logsBloom": "0x04000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000008000000800000000000000000000100000000000000000000000020000000000000000000000010000000000080000010000000000000000000040000000000000000000000004000000000000000000000000000200000000000000000000000000400000000000000000000000000000000004000000002000000000001000000000000000000000000000000100000000000400000000000000000000000000000000000000000000000000100000000100000",
    "blockHash": "0x7c85a7911b5e9c8fb3bf40898167873e4beccd535407fdae3aea777246014936",
    "transactionHash": "0xe632c016cea540b54ccde8343378e615174040fbaae68fce44ab1ea44a89a531",
    "logs": [
        {
            "transactionIndex": 0,
            "blockNumber": 20938930,
            "transactionHash": "0xe632c016cea540b54ccde8343378e615174040fbaae68fce44ab1ea44a89a531",
            "address": "0x2c4eb3c76D7115E210Fadf3cBFe8E0a3d5b8448F",
            "topics": [
                "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
                "0x000000000000000000000000173f8ce8356dd214813f4874c316739f560d8022",
                "0x000000000000000000000000173f8ce8356dd214813f4874c316739f560d8022"
            ],
            "data": "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000",
            "logIndex": 0,
            "blockHash": "0x7c85a7911b5e9c8fb3bf40898167873e4beccd535407fdae3aea777246014936"
        },
        {
            "transactionIndex": 0,
            "blockNumber": 20938930,
            "transactionHash": "0xe632c016cea540b54ccde8343378e615174040fbaae68fce44ab1ea44a89a531",
            "address": "0x0000000000000000000000000000000000001010",
            "topics": [
                "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63",
                "0x0000000000000000000000000000000000000000000000000000000000001010",
                "0x000000000000000000000000173f8ce8356dd214813f4874c316739f560d8022",
                "0x000000000000000000000000f4c2f1d772488cc6d3ec3c703b9710fa2c0e227e"
            ],
            "data": "0x00000000000000000000000000000000000000000000000d3e69b71ddbce800000000000000000000000000000000000000000000010708542e952a17a361000000000000000000000000000000000000000000000ff9c1d5a421812e455d3b8000000000000000000000000000000000000000000107078047f9b839e679000000000000000000000000000000000000000000000ff9c2a98abcf30c02453b8",
            "logIndex": 1,
            "blockHash": "0x7c85a7911b5e9c8fb3bf40898167873e4beccd535407fdae3aea777246014936"
        }
    ],
    "blockNumber": 20938930,
    "confirmations": 2,
    "cumulativeGasUsed": {
        "type": "BigNumber",
        "hex": "0x6a09"
    },
    "effectiveGasPrice": {
        "type": "BigNumber",
        "hex": "0x1ff973cafa8000"
    },
    "status": 1,
    "type": 0,
    "byzantium": true
}

大家可以看到abi只在构建合约的时候用到过一次,其他地方并没有使用到

let contract= new ethers.Contract('合约地址', erc20abi, signer);

下面是abi的样子

[
	{
		"inputs": [
			{
				"internalType": "string",
				"name": "_name",
				"type": "string"
			},
			{
				"internalType": "string",
				"name": "_symbol",
				"type": "string"
			},
			{
				"internalType": "uint256",
				"name": "_decimals",
				"type": "uint256"
			},
			{
				"internalType": "uint256",
				"name": "_totalSupply",
				"type": "uint256"
			}
		],
		"payable": false,
		"stateMutability": "nonpayable",
		"type": "constructor"
	},
	{
		"anonymous": false,
		"inputs": [
			{
				"indexed": true,
				"internalType": "address",
				"name": "_owner",
				"type": "address"
			},
			{
				"indexed": true,
				"internalType": "address",
				"name": "_spender",
				"type": "address"
			},
			{
				"indexed": false,
				"internalType": "uint256",
				"name": "_value",
				"type": "uint256"
			}
		],
		"name": "Approval",
		"type": "event"
	},
	{
		"anonymous": false,
		"inputs": [
			{
				"indexed": true,
				"internalType": "address",
				"name": "_from",
				"type": "address"
			},
			{
				"indexed": true,
				"internalType": "address",
				"name": "_to",
				"type": "address"
			},
			{
				"indexed": false,
				"internalType": "uint256",
				"name": "_value",
				"type": "uint256"
			}
		],
		"name": "Transfer",
		"type": "event"
	},
	{
		"constant": true,
		"inputs": [
			{
				"internalType": "address",
				"name": "_owner",
				"type": "address"
			},
			{
				"internalType": "address",
				"name": "_spender",
				"type": "address"
			}
		],
		"name": "allowance",
		"outputs": [
			{
				"internalType": "uint256",
				"name": "",
				"type": "uint256"
			}
		],
		"payable": false,
		"stateMutability": "view",
		"type": "function"
	},
	{
		"constant": false,
		"inputs": [
			{
				"internalType": "address",
				"name": "_spender",
				"type": "address"
			},
			{
				"internalType": "uint256",
				"name": "_value",
				"type": "uint256"
			}
		],
		"name": "approve",
		"outputs": [
			{
				"internalType": "bool",
				"name": "",
				"type": "bool"
			}
		],
		"payable": false,
		"stateMutability": "nonpayable",
		"type": "function"
	},
	{
		"constant": true,
		"inputs": [
			{
				"internalType": "address",
				"name": "_owner",
				"type": "address"
			}
		],
		"name": "balanceOf",
		"outputs": [
			{
				"internalType": "uint256",
				"name": "",
				"type": "uint256"
			}
		],
		"payable": false,
		"stateMutability": "view",
		"type": "function"
	},
	{
		"constant": true,
		"inputs": [],
		"name": "decimals",
		"outputs": [
			{
				"internalType": "uint256",
				"name": "",
				"type": "uint256"
			}
		],
		"payable": false,
		"stateMutability": "view",
		"type": "function"
	},
	{
		"constant": true,
		"inputs": [],
		"name": "name",
		"outputs": [
			{
				"internalType": "string",
				"name": "",
				"type": "string"
			}
		],
		"payable": false,
		"stateMutability": "view",
		"type": "function"
	},
	{
		"constant": true,
		"inputs": [],
		"name": "symbol",
		"outputs": [
			{
				"internalType": "string",
				"name": "",
				"type": "string"
			}
		],
		"payable": false,
		"stateMutability": "view",
		"type": "function"
	},
	{
		"constant": true,
		"inputs": [],
		"name": "totalSupply",
		"outputs": [
			{
				"internalType": "uint256",
				"name": "",
				"type": "uint256"
			}
		],
		"payable": false,
		"stateMutability": "view",
		"type": "function"
	},
	{
		"constant": false,
		"inputs": [
			{
				"internalType": "address",
				"name": "_to",
				"type": "address"
			},
			{
				"internalType": "uint256",
				"name": "_value",
				"type": "uint256"
			}
		],
		"name": "transfer",
		"outputs": [
			{
				"internalType": "bool",
				"name": "",
				"type": "bool"
			}
		],
		"payable": false,
		"stateMutability": "nonpayable",
		"type": "function"
	},
	{
		"constant": false,
		"inputs": [
			{
				"internalType": "address",
				"name": "_from",
				"type": "address"
			},
			{
				"internalType": "address",
				"name": "_to",
				"type": "address"
			},
			{
				"internalType": "uint256",
				"name": "_value",
				"type": "uint256"
			}
		],
		"name": "transferFrom",
		"outputs": [
			{
				"internalType": "bool",
				"name": "",
				"type": "bool"
			}
		],
		"payable": false,
		"stateMutability": "nonpayable",
		"type": "function"
	}
]

abi就是一个json文件,在合约发布后生成,由solidity工程师导出,前端使用它的主要作用就是构建合约。里面存了这个合约里的所有方法,事件以及请求参数的限制,返回值的类型等等,可以看作是一个接口文档,只不过没有注释。

我们在调用合约的时候会先经过abi的检测,不存在的方法,错误的参数都会直接在这里被拦截,经过abi验证的请求才有可能正常发送给区块。

这里为什么说有可能那,是因为abi只能做到数据类型和方法的判断,至于说方法能不能正常执行下去还是要在合约上过一遍的。

1.构建交易中的对象:从上面的例子中来看,我们通过ether创建了节点,签名者,合约三个对象,然后才能开始和区块上的合约进行交互,如果不引用第三方包我们其实也能构建这三个对象,但效率就不言而喻了。

2.成熟的工具包:区块链上的数据和我们平时给用户看到的实际上相差很大,需要通过一些工具包进行转换,就比如说上面代码中的

ethers.utils.parseEther("1")

他将1变成了1*10**18,如果我们自己计算会有精度损耗不说,当量大时会自动变成科学计数法,给我们带来很多麻烦。

3.交易签名并发送:这点也是最重要的一点,不借助第三方工具包,签名这部分的工作量极大,靠我们个人是完成不了的,而如果使用了ether,我们只需要在构建合约对象时传进去即可,剩下的包ether会帮我们签名并发送,能省下很多步骤。

总的来说使用了ether之后与合约进行交互,写代码的速度甚至要比正常的请求后端要快。

智能合约大前端是什么,智能合约前端常用技巧,前端,智能合约,区块链

下面我们讲一下区块链的执行原理,我们看一下下面这块代码

let data = await contract.transfer("收币地址", ethers.utils.parseEther("1"))
			.catch(function(err) {
							console.log(err)
				})
//data是本次调用生成的链上数据,不是代码执行完后的返回值
console.log(data)
//监听data中的交易hash,来获取交易结果
let data2=await	provider.waitForTransaction(data.hash);
console.log(data2)

其中的data只有交易hash和交易数据,连块hash都没有,更不用说请求结果了,这是为什么?这里我们需要理解一下区块链的运行原理,主要就是矿工费机制的影响。

矿工机制是为了鼓励用户部署节点,完善生态。地址在发起交易的时候需要为这次交易提供矿工费,矿工费由广播这次交易节点获得。

所以用户发起交易后这笔交易只会生成一个待执行的签名信息,其中包括一个唯一的交易hash和要广播的交易数据以及矿工费,然后在队列中等待打包。矿工每次可以打包一个块,一个块收取的矿工费总数是固定的,会优先打包给的矿工费高的交易,打包完后整个块会一起执行,所以如果你发现你的一笔交易迟迟没有反馈结果,就要考虑提高矿工费了。交易被打包成块执行完以后才会给反馈结果。

综上所述,区块链的交易发起和反馈结果在设计上是两部分,需要对应处理。data就是发起部分的数据,data2就是监听这次交易hash获取到的数据。

我一直在使用ether,web3用来写了dom感觉过于繁琐,在实际项目中几乎没有用到,但有些大佬说web3才是厉害的,在此希望懂的朋友给点建议,应该深耕哪个框架,并说下原因文章来源地址https://www.toymoban.com/news/detail-799374.html

到了这里,关于前端请求智能合约的思路的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 区块链智能合约代码示例

            以下是一个简单的区块链智能合约代码示例: 该合约具有以下功能: 定义了一个名为 SimpleContract 的合约。 定义了一个名为 myData 的公共整数变量。 定义了一个名为 setMyData 的公共函数,该函数接受一个 uint 类型的参数 newData,并将其设置为 myData 的新值。 在 So

    2024年02月14日
    浏览(47)
  • 区块链智能合约

    合同(Contract)又称契约、协议,是平等主体的自然人、法人、其他组织之间设立、变更、终止民事权利义务关系的协议。本质上讲,合同是当事双方或多方在并没有充足信任的情况下,通过文字的约定和法律的权威,对各自的权利与义务进行的约定。 制订合同的目的就在于

    2024年01月18日
    浏览(50)
  • 区块链与智能合约

    要想理解什么区块链,我们先来从本质上认识一下它 区块链:本质上是一个去中心化的分布式账本数据库,是指通过去中心化和去信任的方式集体维护一个可靠数据库的技术方法。 没有基础的人可能理解起来有点困难,我们来解释一下里边的名词 分布式账本数据库:了解过

    2024年03月26日
    浏览(91)
  • 区块链智能合约基础

    什么是智能合约 简单来说,智能合约是一种满足在一定条件时,就执行的程序,例如自动售货机就类似一个智能合约系统。 1.向自动售货机投入足够硬币,按下按钮 2.售货机供出商品 3.售货机回到初始状态 智能合约的工作原理 智能合约是一段程序(代码和数据的集合),可

    2024年02月13日
    浏览(44)
  • 区块链智能合约开发学习

    最近正在肝区块链知识学习,入手学习智能合约的开发,由于网上资料实在是太少了,好不容易东拼西凑完成了智能合约的开发、编译、部署、web3js调用(网页页面)和web3j调用(java调用),赶紧趁热把重点提炼出来。 先上图,是我最近学习知识点的一个概括总结,此外还包

    2023年04月18日
    浏览(42)
  • 【区块链 | 审计】智能合约审计指南

    区块链技术正在改变各行各业的游戏规则,而智能合约是这一进程的关键部分。智能合约通过消除第三方中介机构来确保各方之间的信任,有助于降低成本,同时也增加透明度。如果你要写一个智能合约,关键是你要对代码进行审计,以确保它能正常工作--而且不会有任何错

    2024年02月07日
    浏览(54)
  • 区块链2——Solidity智能合约开发

    区块链 索引目录 智能合约是一种以代码形式编写的自动执行合约,它们运行在区块链上。这些合约定义了在特定条件下发生的事件以及相应的行为。 1.1 智能合约结构 版本声明(Version Declaration): 智能合约通常以声明版本开始,指定合约应该使用的Solidity编译器版本。例如

    2024年02月05日
    浏览(69)
  • 人工智能与金融技术:区块链与智能合约

    随着人工智能技术的不断发展,金融领域也在不断融合人工智能技术,为金融服务提供了更多高效、智能化的解决方案。其中,区块链技术和智能合约是人工智能与金融技术的重要组成部分,它们在金融领域中发挥着越来越重要的作用。本文将从以下几个方面进行阐述: 背景

    2024年04月14日
    浏览(93)
  • slither——区块链智能合约静态分析工具

    Slither是一个用Python 3编写的智能合约静态分析框架(源码),提供如下功能: 自动化漏洞检测。提供超30多项的漏洞检查模型,模型列表详见:https://github.com/crytic/slither#detectors 自动优化检测。Slither可以检测编译器遗漏的代码优化项并给出优化建议。 代码理解。Slither能够绘

    2024年01月16日
    浏览(47)
  • 基于区块链智能合约的疫苗溯源系统

    该系统基于以太坊的Solidity进行智能合约开发,并通过hardhat进行部署在了本机,通过Mocha和Chai进行了单元测试的编写,同时提供了一个基于React的前端界面与用户进行交互。 区块链的介绍 不难看出,区块链技术对现有的经济社会产生了巨大的影响。在未来,将会出现越来越多

    2024年02月15日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包