[TOC]
FMZ를 사용하여 에테리움 기반의 웹3 개발에 대한 쉬운 입문
이더리움 (Ethereum) 은 블록체인 기술에 기반한 스마트 계약 플랫폼으로, 스마트 계약을 작성하고 배포하는 데의 분산된 방법을 제공합니다. 스마트 계약은 블록체인에서 자동으로 실행될 수 있는 특수 컴퓨터 프로그램이며, 제3자를 신뢰하지 않아도 다양한 비즈니스 논리를 구현할 수 있습니다.
발명가 양적 거래 플랫폼 (((FMZ.COM에테리움 (Ethereum) 은 개발자가 이더리움 블록체인과 생태계와 더 쉽게 상호 작용할 수 있도록 사용하기 쉬운 API를 제공합니다. 중앙집중화 거래소 (DEX) 를 액세스하고 체인 데이터를 획득하고 거래를 전송하는 등의 기능을 구현합니다.
이 튜토리얼의 예제 사용JavaScript
언어 작성, 테스트 환경 사용이더리움、고엘리 테스트 네트워크▲ FMZ 플랫폼의 API 문서를 통해 이 튜토리얼에서 사용된 API 인터페이스와 관련 설명, 코드 예제를 확인할 수 있다.
FMZ 양적 거래 플랫폼을 사용하기 전에 몇 가지 기본 개념을 알아야합니다.
FMZ의 양적 거래 플랫폼 공식 사이트https://www.fmz.com등록, 로그인 후 플랫폼의 다양한 기능을 사용할 수 있다. FMZ 웹사이트는 전체 시스템의 관리 단말기이며, 사용자가 작성한 프로그램은 실제로 호스트에서 실행된다. 호스트의 이 소프트웨어는 서버, 컴퓨터 등 다양한 장치에 배포될 수 있다. 사용자가 FMZ 웹사이트에서 프로그램을 작성하여 실행 사례를 만들 때, FMZ 플랫폼은 호스트와 통신하여 호스트에서 프로그램 사례를 실행한다.
실행되는 경우 호스트를 배치해야 하며, 호스트 배포는 매우 간단하며, 플랫폼에 배포 설명서가 있습니다. FMZ에서 제공되는 "하나의 키 배포 관리자"를 사용하여 FMZ를 대신하여 렌터 서버를 사용하여 자동 배포 할 수도 있습니다.
개인 기기에 호스트를 배포
서버, 개인용 컴퓨터 등의 장치에 실행 관리자 프로그램을 배포할 수 있으며, 네트워크가 정상적으로 작동하는 것을 보장하는 한 (거래소 인터페이스, 노드 주소 등과 같은 해당 목표에 액세스 할 필요가 있습니다.) 배포의 주요 단계는 다음과 같습니다.
1, 로그인하거나 호스트 프로그램을 배포하려는 장치를 열기, 예를 들어서버에 로그인합니다또는컴퓨터가 운영 체제에 접속하도록ᅳ
2, 해당 버전의 호스트 프로그램을 다운로드 (기기 운영 체제에 따라) 다운로드 페이지:https://www.fmz.com/m/add-node
3, 다운로드 한 압축 패키지, 압축을 풀 필요가 있습니다.
4. 이 관리자 프로그램을 실행합니다. 관리자 프로그램은robot
이 파일의 실행 파일. FMZ에 접속한 후 FMZ에 접속할 수 있는 모든 FMZ 계정에 고유한 호스트 통신 주소를 설정합니다.https://www.fmz.com/m/add-node
이 페이지에서 자신의 주소를 확인할 수 있습니다../robot -s node.fmz.com/xxxxx
이 주소는 여기 있습니다.xxxxx
위치의 내용, 각 FMZ 계정이 표시하는 것은 다릅니다.);; 마지막으로 FMZ 계정의 암호를 입력해야 합니다.
FMZ 플랫폼의 "하나의 클릭으로 호스트를 배포" 기능을 사용
FMZ 플랫폼에서 주관자 페이지를 추가합니다.https://www.fmz.com/m/add-node
FMZ 양적 거래 플랫폼은 무료 디뷰팅 도구를 제공합니다.JavaScript
,TypeScript
이 페이지의 제목은:https://www.fmz.com/m/debug, 인스턴스 실행을 만드는 것은 수수료이기 때문에. 초등학교 기간 동안 이 디비팅 도구를 사용하여 테스트, 학습을 할 수 있다. 디비팅 도구는 실행 시간이 최대 3분으로 제한되는 것을 제외하고는 다른 측면과 크리에이팅 인스턴스 실행을 구분하지 않는다.
사용TypeScript
언어의 경우, 코드의 첫 줄에 글을 써야 합니다.// @ts-check
이 자리에서TypeScript
모드, 스위치하지 않는 것은 기본적으로JavaScript
언어는
FMZ에서 "거래소"는 범용 개념이며, CEX 거래소에서는 특정 거래소 계정 설정을 의미한다. web3에서는 이 거래소가 노드 주소, 개인 키 설정을 포함하는 설정을 의미한다.
FMZ 플랫폼에 접속하면,https://www.fmz.com/m/add-platform
이 페이지에서는 거래소 정보를 구성할 수 있으며, 여기서 거래소는 범용 개념입니다.
선택Web3
, RPC 노드 주소를 설정, 개인 키를 설정하면, 오른쪽 하단에 있는 "비밀정보를 독립적인 개인 키로 암호화 저장"을 클릭하여 보안 장치를 볼 수 있다.
노드는 자체적으로 만든 노드나 노드 서버에서 제공하는 노드를 사용할 수 있습니다. 노드 서버는 많이 있습니다. 예를 들어:인푸라▲ 등록 후 자신의 계정의 노트 주소를 확인할 수 있습니다. ▲ 홈 웹, 테스트 웹이 있습니다, 비교적 편리합니다.Rpc Address
이 지표는 자신의 이름을 붙여서 구성된 거래소 객체를 구별하는 데 사용할 수 있습니다.
그림에서https://mainnet.infura.io/v3/xxxxxxxxxxxxx
인푸라의 ETH 메인 네트워크의 RPC 노드 주소입니다.
在部署好托管者程序、配置好交易所对象的前提下,就可以使用FMZ.COM的「调试工具」进行测试了。调用以太坊RPC方法和以太坊交互,除了本章节列举介绍的几个RPC方法,其它RPC方法可以查询资料了解,例如https://www.quicknode.com/docs。
우리는 몇 가지 간단한 예제를 소개하고 기본부터 시작합니다. 다양한 언어와 도구에 대해 웹3에 접근할 수 있는 방법이 있습니다.
FMZ에서 RPC 메소드 호출을 위한 기능도 FMZ의 API 기능에 포괄되어 있습니다.exchange.IO
중 ◎ 호출 방식은exchange.IO("api", "eth", ...)
◎ 첫 번째 매개 변수는 고정 전송"api"
두 번째 매개 변수는 고정된 입력입니다."eth"
다른 매개 변수는 특정 호출된 RPC 방법에 따라 결정됩니다.
우리는 FMZ 플랫폼을 사용하여 정보를 출력합니다.Log
이 함수들은Log
함수는 여러 개의 매개 변수를 입력하고 FMZ 플랫폼의 "Debugging Tool" 또는 "RealDisk" 페이지의 로그 영역에서 "Debugging Tool" 페이지가 우리가 테스트하는 주요 도구가 될 것입니다.
이더리움eth_getBalance
에테리움 주소에 있는 ETH 잔액을 검색하는 방법. 이 방법은 2개의 매개 변수를 입력해야 한다.
에테리움의 창업자를 찾아보죠.V神
ETH 지갑의 주소는 다음과 같습니다.0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
。
function main() {
let ethBalance = exchange.IO("api", "eth", "eth_getBalance", "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "latest")
Log("ethBalance:", ethBalance)
}
관리자를 배포하고 거래소 객체를 구성하고 있으며, 디뷰팅 도구에서 코드를 테스트합니다.
이 코드를 실행하기 위해 실행 버튼을 누르면 다음과 같은 결과를 볼 수 있습니다.
eth평형: 0x117296558f185bbc4c6
Log
이 함수들은ethBalance
변수 값은:0x117296558f185bbc4c6
,는 문자열 타입입니다.16자리 기준의 ETH 잔액그리고wei
이 모든 것은1e18 wei
1입니다.ETH
그래서 변환이 필요하기 때문에 읽을 수 있는 십진수 ETH 잔액으로 변환됩니다.
그리고ethBalance
이 자료를 읽을 수 있는 데이터로 변환합니다.
function main() {
let ethBalance = exchange.IO("api", "eth", "eth_getBalance", "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "latest")
Log("ethBalance:", ethBalance)
// 将ethBalance转换为可读的数据
let vitalikEthBalance = parseInt(ethBalance.substring(2), 16) / 1e18
Log("vitalikEthBalance:", vitalikEthBalance)
}
위쪽https://etherscan.io/
질문:
그러나 언어 자체의 정확성에 대한 문제로 인해 오류가 발생할 수 있기 때문에 FMZ 플랫폼은 데이터를 처리하기 위해 두 가지 기능을 내장했습니다.
코드를 다시 조정합니다:
function main() {
let ethBalance = exchange.IO("api", "eth", "eth_getBalance", "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "latest")
// ETH的精度单位为1e18
let ethDecimal = 18
Log("vitalikEthBalance:", Number((BigDecimal(BigInt(ethBalance)) / BigDecimal(Math.pow(10, ethDecimal))).toString()))
}
비탈릭 에스 밸런스: 5149.6244846875215
eth_chainId
그리고net_version
이 두 함수는 현재 RPC 노트 접속된 블록 체인의 Id를 반환합니다.net_version
10분의 1의 10분의 1의 10분의 1의 10분의 1의eth_chainId
16개 계열의 Id 를 반환합니다.
ChainId에 해당하는 네트워크 이름
1 - ethereum mainnet
2 - morden testnet (deprecated)
3 - ropsten testnet
4 - rinkeby testnet
5 - goerli testnet
11155111 - sepolia testnet
10 - optimism mainnet
69 - optimism kovan testnet
42 - kovan testnet
137 - matic/polygon mainnet
80001 - matic/polygon mumbai testnet
250 - fantom mainnet
100 - xdai mainnet
56 - bsc mainnet
에테리움 테스트 네트워크goerli
노드 테스트:
function main() {
let netVersionId = exchange.IO("api", "eth", "net_version")
let ethChainId = exchange.IO("api", "eth", "eth_chainId")
Log("netVersionId:", netVersionId)
Log("ethChainId:", ethChainId, " ,转换:", parseInt(ethChainId.substring(2), 16))
}
전화eth_gasPrice
메소드, 현재 링크를 검색gas price
。
function toAmount(s, decimals) {
return Number((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
}
function main() {
let gasPrice = exchange.IO("api", "eth", "eth_gasPrice")
Log("gasPrice:", gasPrice, " ,转换:", toAmount(gasPrice, 0))
}
여기 우리는 16자리 문자열을 읽을 수 있는 숫자로 변환하는 작업을 함수로 작성했습니다.toAmount
또한, 가스 가격의 단위는wei
그래서,decimals
해당 실제변수변수값은 0이다.
eth_blockNumbe
블록의 높이를 검색하기 위해 사용되죠.
function toAmount(s, decimals) {
return Number((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
}
function main() {
let blockNumber = exchange.IO("api", "eth", "eth_blockNumber")
Log(toAmount(blockNumber, 0))
}
디뷰팅 도구에서 실행:
https://etherscan.io/
이 문서를 검색하세요:
이 블로그의 내용은 다음과 같습니다:
function main() {
let blockNumber = exchange.IO("api", "eth", "eth_blockNumber")
Log(blockNumber)
let blockMsg = exchange.IO("api", "eth", "eth_getBlockByNumber", blockNumber, true)
Log(typeof(blockMsg), blockMsg)
// 由于Log输出的内容过多,会自动截断,所以遍历返回的区块信息各个字段,逐个打印
for (let key in blockMsg) {
Log("key:", key, ", val:", blockMsg[key])
}
}
"디맥업 도구"에서 실행하면 다음과 같은 정보를 얻을 수 있습니다.
에테리움에는 수많은 스마트 컨트랙트 애플리케이션이 운영되고 있습니다.ENS
그리고 그 중 하나가 바로 이겁니다.ENS
에테리움 도메인 이름 서비스 (Ethereum Name Service) 는 에테리움 블록체인 기반의 분산된 도메인 이름 분석 서비스이다.
에테리움의 창업자인 V의 지갑 잔액의 예제를 확인한 튜토리얼 기억하시나요?0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
ᅳ 그렇다면 우리는 이 주소를 어떻게 알 수 있을까요?ENS
스마트 계약, 직관적인 이름을 사용vitalik.eth
이 문서는 '비탈릭 (V의 이름) '을 검색하기 위한 것입니다.
이 장의 다음 내용은 에테리움 환경을 사용하여ENS
문서는 Ethereum 도메인 이름에 대한 검색이 필요하다는 것을 알고 있습니다.Hashing Names
다음 코드를 사용해서vitalik.eth
이 글의 제목은 처리됩니다.
function nameHash(name) {
if (name == "") {
return "0000000000000000000000000000000000000000000000000000000000000000"
} else {
let arr = name.split(".")
let label = arr[0]
arr.shift()
let remainder = arr.join(".")
return Encode("sha3.keccak256", "hex", "hex", nameHash(remainder) + Encode("sha3.keccak256", "raw", "hex", label))
}
}
이 코드 예제에서 우리는 또 다른 이상한 함수를 볼 수 있습니다.Encode
이 함수는 FMZ 플랫폼의 API 함수이며, FMZ 플랫폼에서 암호화 작업을 수행하기 위해 특별히 사용되며, 여러 코딩 방식을 지원하고 여러 해시 알고리즘을 지원합니다.
Encode(algo, inputFormat, outputFormat, data, keyFormat, key string)
ENS 문서에 설명된 바에 따라 사용sha3.keccak256
알고리즘은 데이터를 처리합니다.
전화nameHash
예를 들어,Log(nameHash("vitalik.eth"))
이 글은ee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835
이 경우, 우리는 0x 앞자리를 추가해야 합니다.0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835
이 프로젝트의 핵심은resolver
방법의 매개 변수.
let ensNode = "0x" + nameHash("vitalik.eth") // 准备好调用resolver方法的参数ensNode
ENS 문서를 검색하면 ENS 스마트 계약 응용 프로그램의 계약 주소가 다음과 같습니다.0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
◎ 스마트 계약에 대한 요청resolver
이 방법은 우리가 계약서를 준비해야 할 방법 중 하나입니다.ABI
。
이 곳에 온 사람들은 항상 물어볼 수 있습니다.ABI
이봐요
ABI,即应用程序二进制接口(Application Binary Interface),是智能合约与外部世界进行通信的接口标准。
智能合约的 ABI 定义了合约的函数接口、参数类型、返回值等信息,以及调用合约的方式和参数传递方式等规范。
智能合约的 ABI 通常以 JSON 格式存储,包含以下信息:
合约的函数接口:函数名、参数列表、返回值等信息。
函数参数类型:如 uint256、bool、string 等。
函数的输入参数和输出参数的编码方式:智能合约使用一种称为 Solidity ABI 的编码方式来编码函数的输入参数和输出参数,
以便与以太坊网络进行交互。
在以太坊网络中,使用智能合约的 ABI 来调用合约的函数。当需要调用合约函数时,需要提供函数名和函数参数,以及将函数参数按照 ABI 编码方式编码后的字节码。
以太坊节点会将这些信息打包成一笔交易,并将交易发送到以太坊网络中执行。
智能合约的 ABI 在 Solidity 语言中可以通过 interface 关键字来定义。以太坊开发工具如 Remix IDE、Truffle 等也提供了 ABI 编辑和生成工具,
使得开发者可以方便地创建和使用智能合约的 ABI。
이 자료를 가져와서resolver
ABI를 사용할 수 있습니다.https://etherscan.io/
계약에 대한 ABI를 검색하거나 다른 방법으로 ABI를 얻을 수 있습니다 (예: 관련 프로젝트 문서).
let abiENS_resolver = `[{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"resolver","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]`
우리는 FMZ 플랫폼에서 새로운 통화를 배우고 있습니다.exchange.IO("abi", address, abiContent)
이 방법을 사용하여 ABI를 등록합니다.address
이 지표는 스마트 계약의 주소입니다.abiContent
변수는 대응하는 스마트 계약 ABI (string) 이다.
let abiENS_resolver = `[{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"resolver","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]`
exchange.IO("abi", "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", abiENS_resolver) // 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e 是在以太坊主网上部署的ENS智能合约的地址
그리고는 E.N.S. 스마트 컨트랙트를 호출할 수 있습니다resolver
이 방법은 다시 돌아갑니다.ENS: Public Resolver
계약의 주소는.
let resolverAddress = exchange.IO("api", "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", "resolver", ensNode)
사용ENS: Public Resolver
계약addr
V의 지갑 주소를 얻는 방법.ENS: Public Resolver
계약은 여전히 ABI를 등록해야 합니다. 이 스마트 계약의 ABI 정보는 여전히https://etherscan.io/
이 글은 제 3번째입니다.
let abiENSPublicResolver = `[{"inputs":[{"internalType":"contract ENS","name":"_ens","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"contentType","type":"uint256"}],"name":"ABIChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"address","name":"a","type":"address"}],"name":"AddrChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"coinType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"newAddress","type":"bytes"}],"name":"AddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bool","name":"isAuthorised","type":"bool"}],"name":"AuthorisationChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"hash","type":"bytes"}],"name":"ContenthashChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"name","type":"bytes"},{"indexed":false,"internalType":"uint16","name":"resource","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"record","type":"bytes"}],"name":"DNSRecordChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"name","type":"bytes"},{"indexed":false,"internalType":"uint16","name":"resource","type":"uint16"}],"name":"DNSRecordDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"DNSZoneCleared","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"bytes4","name":"interfaceID","type":"bytes4"},{"indexed":false,"internalType":"address","name":"implementer","type":"address"}],"name":"InterfaceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"NameChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"x","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"y","type":"bytes32"}],"name":"PubkeyChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"string","name":"indexedKey","type":"string"},{"indexed":false,"internalType":"string","name":"key","type":"string"}],"name":"TextChanged","type":"event"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"contentTypes","type":"uint256"}],"name":"ABI","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"addr","outputs":[{"internalType":"address payable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"coinType","type":"uint256"}],"name":"addr","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"authorisations","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"clearDNSZone","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"contenthash","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"name","type":"bytes32"},{"internalType":"uint16","name":"resource","type":"uint16"}],"name":"dnsRecord","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"name","type":"bytes32"}],"name":"hasDNSRecords","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"interfaceImplementer","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"pubkey","outputs":[{"internalType":"bytes32","name":"x","type":"bytes32"},{"internalType":"bytes32","name":"y","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"contentType","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setABI","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"coinType","type":"uint256"},{"internalType":"bytes","name":"a","type":"bytes"}],"name":"setAddr","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"a","type":"address"}],"name":"setAddr","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"isAuthorised","type":"bool"}],"name":"setAuthorisation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes","name":"hash","type":"bytes"}],"name":"setContenthash","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setDNSRecords","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes4","name":"interfaceID","type":"bytes4"},{"internalType":"address","name":"implementer","type":"address"}],"name":"setInterface","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"name","type":"string"}],"name":"setName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"x","type":"bytes32"},{"internalType":"bytes32","name":"y","type":"bytes32"}],"name":"setPubkey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"key","type":"string"},{"internalType":"string","name":"value","type":"string"}],"name":"setText","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"key","type":"string"}],"name":"text","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}]`
exchange.IO("abi", resolverAddress, abiENSPublicResolver)
마지막 전화ENS: Public Resolver
계약addr
그 방법, 그 매개 변수는 여전히ensNode
。
let vitalikAddress = exchange.IO("api", resolverAddress, "addr", ensNode)
Log("vitalikAddress:", vitalikAddress)
로그 함수 출력:
vitalikAddress: 0xd8da6bf26964af9d7eed9e03e53415d37aa96045
function nameHash(name) {
if (name == "") {
return "0000000000000000000000000000000000000000000000000000000000000000"
} else {
let arr = name.split(".")
let label = arr[0]
arr.shift()
let remainder = arr.join(".")
return Encode("sha3.keccak256", "hex", "hex", nameHash(remainder) + Encode("sha3.keccak256", "raw", "hex", label))
}
}
function main() {
// 计算名称
let ensNode = "0x" + nameHash("vitalik.eth")
// 注册ENS合约
let abiENS_resolver = `[{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"resolver","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]`
exchange.IO("abi", "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", abiENS_resolver)
let resolverAddress = exchange.IO("api", "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", "resolver", ensNode)
// 注册ENS Public Resolver合约
let abiENSPublicResolver = `[{"inputs":[{"internalType":"contract ENS","name":"_ens","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"contentType","type":"uint256"}],"name":"ABIChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"address","name":"a","type":"address"}],"name":"AddrChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"coinType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"newAddress","type":"bytes"}],"name":"AddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bool","name":"isAuthorised","type":"bool"}],"name":"AuthorisationChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"hash","type":"bytes"}],"name":"ContenthashChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"name","type":"bytes"},{"indexed":false,"internalType":"uint16","name":"resource","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"record","type":"bytes"}],"name":"DNSRecordChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"name","type":"bytes"},{"indexed":false,"internalType":"uint16","name":"resource","type":"uint16"}],"name":"DNSRecordDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"DNSZoneCleared","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"bytes4","name":"interfaceID","type":"bytes4"},{"indexed":false,"internalType":"address","name":"implementer","type":"address"}],"name":"InterfaceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"NameChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"x","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"y","type":"bytes32"}],"name":"PubkeyChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"string","name":"indexedKey","type":"string"},{"indexed":false,"internalType":"string","name":"key","type":"string"}],"name":"TextChanged","type":"event"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"contentTypes","type":"uint256"}],"name":"ABI","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"addr","outputs":[{"internalType":"address payable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"coinType","type":"uint256"}],"name":"addr","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"authorisations","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"clearDNSZone","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"contenthash","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"name","type":"bytes32"},{"internalType":"uint16","name":"resource","type":"uint16"}],"name":"dnsRecord","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"name","type":"bytes32"}],"name":"hasDNSRecords","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"interfaceImplementer","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"pubkey","outputs":[{"internalType":"bytes32","name":"x","type":"bytes32"},{"internalType":"bytes32","name":"y","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"contentType","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setABI","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"coinType","type":"uint256"},{"internalType":"bytes","name":"a","type":"bytes"}],"name":"setAddr","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"a","type":"address"}],"name":"setAddr","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"isAuthorised","type":"bool"}],"name":"setAuthorisation","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes","name":"hash","type":"bytes"}],"name":"setContenthash","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setDNSRecords","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes4","name":"interfaceID","type":"bytes4"},{"internalType":"address","name":"implementer","type":"address"}],"name":"setInterface","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"name","type":"string"}],"name":"setName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"x","type":"bytes32"},{"internalType":"bytes32","name":"y","type":"bytes32"}],"name":"setPubkey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"key","type":"string"},{"internalType":"string","name":"value","type":"string"}],"name":"setText","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"key","type":"string"}],"name":"text","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}]`
exchange.IO("abi", resolverAddress, abiENSPublicResolver)
let vitalikAddress = exchange.IO("api", resolverAddress, "addr", ensNode)
Log("vitalikAddress:", vitalikAddress)
}
이전 강의에서 우리는 개인 키를 구성하는 방법을 배웠습니다. 개인 키가 해당 지갑 주소인지 어떻게 알 수 있을까요?exchange.IO("address")
함수는 설정된 개인 키에 해당하는 지갑 주소를 얻습니다.
이 장의 다음의 내용이 사용됨에 따라Goerli
그래서 제가 사용하는 노드는 다음과 같습니다.https://goerli.infura.io/v3/*******
인푸라는 등록된 사용자마다 다른 노드 주소를 할당합니다.*******
이 글은 멘토의 글입니다.
function main() {
let walletAddress = exchange.IO("address")
Log("测试网 goerli 钱包地址:", walletAddress)
}
자금 지갑 주소를 알고 나면 Ethereum의 RPC 방법을 사용할 수 있습니다.eth_getTransactionCount
지갑 주소를 검색하는 거래 수. 이 트랜잭션 수는 이더리움에서 매우 자주 사용되며, 실제로는 송금 작업에 입력되어야합니다.nonce
매개 변수, 에테리움에서, nonce는 각 거래가 고유한 숫자임을 확인하기 위해 사용된다. 그것은 증가하는 숫자이며, 새로운 거래가 전송될 때마다 자동으로 증가한다. 따라서, 당신이 스마트 계약에 거래를 전송할 때, 거래가 독특하고 순서가 올바르다는 것을 확인하기 위해 nonce를 제공해야 한다.
여기 Go 언어의 에테리움 저장소에서PendingNonceAt
함수들은 실제로 호출되는 것입니다.eth_getTransactionCount
방법. 이전 강의에서도 RPC 방법을 어떻게 호출하는지를 배웠고, 여기서 다시 사용합니다.exchange.IO("api", "eth", ...)
이 함수들은
function toAmount(s, decimals) {
return Number((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
}
function main() {
let walletAddress = exchange.IO("address")
Log("测试网 goerli 钱包地址:", walletAddress)
/**
* eth_getTransactionCount
* @param address - string - The address from which the transaction count to be checked.
* @param blockNumber - string - The block number as a string in hexadecimal format or tags.
* @returns The integer of the number of transactions sent from an address encoded as hexadecimal.
*/
let nonce = exchange.IO("api", "eth", "eth_getTransactionCount", walletAddress, "pending")
Log("钱包地址:", walletAddress, "当前的 nonce:", nonce, ",转换为10进制:", toAmount(nonce, 0))
}
이 트랜스포먼트 작업에 대해 설명하기 전에, 이터리움에서 트랜스포먼트 시 일정한 ETH 토큰이 소모되는 개념에 대해 간단히 설명합니다. 이 가스 비용은 두 가지 매개 변수로 결정됩니다.
가스 가격
그러나 이더리움 네트워크의 가스 요금은 시장 수요와 사용자가 기꺼이 지불하는 비용에 따라 항상 변동하기 때문에 코드에 고정된 가스 요금을 작성하는 것이 때로는 이상적인 선택이 아닙니다.eth_gasPrice
이 방법은 평균 가스 가격을 얻을 수 있습니다.
가스 제한
표준 에테리언 트랜스포먼트의 가스 제한은 21000 유닛이다.
알겠습니다.nonce
,gasPrice
,gasLimit
이 개념들은 전송을 테스트 할 수 있습니다. FMZ에 포장된 매우 간단하고 사용하기 쉬운 전송 함수.
exchange.IO("api", "eth", "send", toAddress, toAmount)
이 글은 유저들의 관심과 관심의 대상이 되었습니다.exchange.IO
이 문서는 "Send"이라는 문자로 작성된 것입니다.toAddress
이 매개 변수는 트랜스포먼트 시 ETH를 수신하는 주소입니다.toAmount
트랜스포팅에 필요한 ETH의 양.
nonce
,gasPrice
,gasLimit
이 매개 변수는 FMZ에서 시스템에서 기본으로 자동으로 얻는 값을 사용할 수 있습니다.
exchange.IO("api", "eth", "send", toAddress, toAmount, {gasPrice: 5000000000, gasLimit: 21000, nonce: 100})
다음으로 우리는 테스트 웹 goerli에서 특정 주소로 특정 ETH를 전송합니다:
function toInnerAmount(s, decimals) {
return (BigDecimal(s)*BigDecimal(Math.pow(10, decimals))).toFixed(0)
}
function main() {
let walletAddress = exchange.IO("address")
Log("测试网 goerli 钱包地址:", walletAddress)
let ret = exchange.IO("api", "eth", "send", "0x4D75a08E870674E68cAE611f329A27f446A66813", toInnerAmount(0.01, 18))
return ret // 返回Transaction Hash : 0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e
}
이더리움의 트랜스포먼트 단위는wei
자, 이제 이 문맥을 더 자세히 살펴보겠습니다.toInnerAmount
그 다음으로wei
단위의 값은 ▲
이쪽에서https://etherscan.io/
트랜잭션 해시를 검색합니다:0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e
。
또한 코드 쿼리 전송 해시를 작성할 수 있습니다.0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e
, 사용eth_getTransactionReceipt
어떤 방법으로 문의할 수 있나요?
function main() {
let transHash = "0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e"
let info = exchange.IO("api", "eth", "eth_getTransactionReceipt", transHash)
return info
}
검색결과:
{
"cumulativeGasUsed": "0x200850",
"effectiveGasPrice": "0x1748774421",
"transactionHash": "0xa6f9f51b00d8ae850b0f204380b59da98f4bbce34b813577d3d948f61de4734e",
"type": "0x0",
"blockHash": "0x6bdde8b0f0453ecd24eecf7c634d65306f05511e0e8f09f9ed3f59eee2d06ac7",
"contractAddress": null,
"blockNumber": "0x868a50",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"gasUsed": "0x5208",
"to": "0x4d75a08e870674e68cae611f329a27f446a66813",
"status": "0x1",
"transactionIndex": "0x23",
"from": "0x6b3f11d807809b0b1e5e3243df04a280d9f94bf4",
"logs": []
}
각 필드의 설명은 다음과 같습니다.
blockHash - 该交易所在区块的哈希值
blockNumber - 以十六进制编码的该交易所在区块的块号
contractAddress - 如果是合约创建,该合约的地址;否则为null
cumulativeGasUsed - 该交易在区块中执行时使用的总燃气量
effectiveGasPrice - 每单位燃气的总基础费用加小费
from - 发送者的地址
gasUsed - 该特定交易使用的燃气量
logs - 生成该交易的日志对象数组
address - 生成该日志的地址
topics - 0到4个32字节索引日志参数的数据数组。在Solidity中,第一个主题是事件签名的哈希值(例如Deposit(address,bytes32,uint256)),除非你使用匿名说明符声明该事件
data - 日志的32字节非索引参数
blockNumber - 该日志所在区块的块号
transactionHash - 该日志创建时的交易哈希值。如果该日志处于待定状态,则为null
transactionIndex - 该日志创建时的交易索引位置。如果该日志处于待定状态,则为null
blockHash - 该日志所在区块的哈希值
logIndex - 该日志在区块中的索引位置,以十六进制编码的整数。如果该日志处于待定状态,则为null
removed - 如果该日志已被删除,则为true,由于链重组而被删除;如果是有效的日志,则为false
logsBloom - 用于检索相关日志的布隆过滤器
status - 以十六进制编码的值,它要么是1(成功),要么是0(失败)
to - 接收者的地址。如果是合约创建交易,则为null
transactionHash - 该交易的哈希值
transactionIndex - 以十六进制编码的该交易在区块中的索引位置
type - 值的类型
우리는계약 정보를 읽습니다.이 장에서는 에테리움에 배포된 ENS 계약의 방법을 호출하여 V의 지갑 주소를 얻는 완전한 예제를 통해 설명합니다.Read
이 방법들을 호출할 필요가 없습니다.gas
에테리온에 있는 스마트 컨트랙트 (smart contract) 에 대해 이야기 해 보겠습니다.Write
방법과 지불gas
이러한 작업은 네트워크 전체의 모든 노트와 채굴자들에 의해 검증되고 블록체인의 상태를 변화시킵니다.
ERC20 계약 (ERC20 토큰 계약) 을 위해 FMZ 플랫폼은 ERC20 계약의 ABI를 일반적인 ABI로 직접 시스템에 내장하여 등록 ABI 단계를 생략합니다.
ABI를 더 잘 이해하기 위해, 사용하기 전에 아래와 같은 ABI를 살펴볼 수 있습니다.
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"deposit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Withdrawal","type":"event"}]
이 장의 다음의 내용이 사용됩니다.Goerli
인터넷 환경 테스트.
그리고 나서 우리는 다시 한 번 연습을 해봤습니다.Read
어떻게 계약 정보를 읽고 ERC20 계약을 호출할 수 있는지balanceOf
토큰 잔액을 검색하는 방법balanceOf
메소드에는 하나의 매개 변수가 있지만 이름이 없으며, 타입에 의해 주소 (즉, 질의하는 토큰 주소) 로 볼 수 있습니다. 반환된 데이터가 토큰 단위로 구성되어 있지 않기 때문에 토큰의 정확도 데이터가 필요하기 때문에 토큰의 정확도가 ERC20 계약을 통해 계산 될 수 있습니다.decimals
접근 방법. 우리는 이더리움 테스트 네트워크를 사용합니다.goerli
테스트를 수행하고, 다른 체인 상의 토큰 계약 주소가 다를 수 있다는 것을 유의하십시오.
function toAmount(s, decimals) {
return Number((BigDecimal(BigInt(s)) / BigDecimal(Math.pow(10, decimals))).toString())
}
function main() {
let walletAddress = exchange.IO("address")
// goerli WETH address
let wethAddress = "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6"
// goerli LINK address
let linkAddress = "0x326C977E6efc84E512bB9C30f76E30c160eD06FB"
// 由于是ERC20合约,FMZ已经内置ABI注册,所以这里不用注册ERC20 ABI
let wethDecimals = exchange.IO("api", wethAddress, "decimals")
let linkDecimals = exchange.IO("api", linkAddress, "decimals")
let wethBalance = exchange.IO("api", wethAddress, "balanceOf", walletAddress)
let linkBalance = exchange.IO("api", linkAddres