FMZ를 사용하여 에테리움 기반의 웹3 개발에 대한 쉬운 입문

저자:작은 꿈, 창작: 2023-03-28 13:32:48, 업데이트: 2023-09-18 20:27:13

[TOC]

img

이더이즈와FMZ 교육

FMZ를 사용하여 에테리움 기반의 웹3 개발에 대한 쉬운 입문

이더리움 (Ethereum) 은 블록체인 기술에 기반한 스마트 계약 플랫폼으로, 스마트 계약을 작성하고 배포하는 데의 분산된 방법을 제공합니다. 스마트 계약은 블록체인에서 자동으로 실행될 수 있는 특수 컴퓨터 프로그램이며, 제3자를 신뢰하지 않아도 다양한 비즈니스 논리를 구현할 수 있습니다.

발명가 양적 거래 플랫폼 (((FMZ.COM에테리움 (Ethereum) 은 개발자가 이더리움 블록체인과 생태계와 더 쉽게 상호 작용할 수 있도록 사용하기 쉬운 API를 제공합니다. 중앙집중화 거래소 (DEX) 를 액세스하고 체인 데이터를 획득하고 거래를 전송하는 등의 기능을 구현합니다.

이 튜토리얼의 예제 사용JavaScript언어 작성, 테스트 환경 사용이더리움고엘리 테스트 네트워크▲ FMZ 플랫폼의 API 문서를 통해 이 튜토리얼에서 사용된 API 인터페이스와 관련 설명, 코드 예제를 확인할 수 있다.


FMZ의 사용

FMZ 양적 거래 플랫폼을 사용하기 전에 몇 가지 기본 개념을 알아야합니다.

1, FMZ 양적 거래 플랫폼 구조

FMZ의 양적 거래 플랫폼 공식 사이트https://www.fmz.com등록, 로그인 후 플랫폼의 다양한 기능을 사용할 수 있다. FMZ 웹사이트는 전체 시스템의 관리 단말기이며, 사용자가 작성한 프로그램은 실제로 호스트에서 실행된다. 호스트의 이 소프트웨어는 서버, 컴퓨터 등 다양한 장치에 배포될 수 있다. 사용자가 FMZ 웹사이트에서 프로그램을 작성하여 실행 사례를 만들 때, FMZ 플랫폼은 호스트와 통신하여 호스트에서 프로그램 사례를 실행한다.

img

2 관리자

실행되는 경우 호스트를 배치해야 하며, 호스트 배포는 매우 간단하며, 플랫폼에 배포 설명서가 있습니다. FMZ에서 제공되는 "하나의 키 배포 관리자"를 사용하여 FMZ를 대신하여 렌터 서버를 사용하여 자동 배포 할 수도 있습니다.

  • 개인 기기에 호스트를 배포

    서버, 개인용 컴퓨터 등의 장치에 실행 관리자 프로그램을 배포할 수 있으며, 네트워크가 정상적으로 작동하는 것을 보장하는 한 (거래소 인터페이스, 노드 주소 등과 같은 해당 목표에 액세스 할 필요가 있습니다.) 배포의 주요 단계는 다음과 같습니다.

    1, 로그인하거나 호스트 프로그램을 배포하려는 장치를 열기, 예를 들어서버에 로그인합니다또는컴퓨터가 운영 체제에 접속하도록ᅳ 2, 해당 버전의 호스트 프로그램을 다운로드 (기기 운영 체제에 따라) 다운로드 페이지:https://www.fmz.com/m/add-node img3, 다운로드 한 압축 패키지, 압축을 풀 필요가 있습니다. 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

    img

3, 디뷰팅 도구

FMZ 양적 거래 플랫폼은 무료 디뷰팅 도구를 제공합니다.JavaScriptTypeScript이 페이지의 제목은:https://www.fmz.com/m/debug, 인스턴스 실행을 만드는 것은 수수료이기 때문에. 초등학교 기간 동안 이 디비팅 도구를 사용하여 테스트, 학습을 할 수 있다. 디비팅 도구는 실행 시간이 최대 3분으로 제한되는 것을 제외하고는 다른 측면과 크리에이팅 인스턴스 실행을 구분하지 않는다.

사용TypeScript언어의 경우, 코드의 첫 줄에 글을 써야 합니다.// @ts-check이 자리에서TypeScript모드, 스위치하지 않는 것은 기본적으로JavaScript언어는

4 거래소

FMZ에서 "거래소"는 범용 개념이며, CEX 거래소에서는 특정 거래소 계정 설정을 의미한다. web3에서는 이 거래소가 노드 주소, 개인 키 설정을 포함하는 설정을 의미한다.

FMZ 플랫폼에 접속하면,https://www.fmz.com/m/add-platform이 페이지에서는 거래소 정보를 구성할 수 있으며, 여기서 거래소는 범용 개념입니다.

img

선택Web3, RPC 노드 주소를 설정, 개인 키를 설정하면, 오른쪽 하단에 있는 "비밀정보를 독립적인 개인 키로 암호화 저장"을 클릭하여 보안 장치를 볼 수 있다.

노드는 자체적으로 만든 노드나 노드 서버에서 제공하는 노드를 사용할 수 있습니다. 노드 서버는 많이 있습니다. 예를 들어:인푸라▲ 등록 후 자신의 계정의 노트 주소를 확인할 수 있습니다. ▲ 홈 웹, 테스트 웹이 있습니다, 비교적 편리합니다.Rpc Address이 지표는 자신의 이름을 붙여서 구성된 거래소 객체를 구별하는 데 사용할 수 있습니다.

img

그림에서https://mainnet.infura.io/v3/xxxxxxxxxxxxx인푸라의 ETH 메인 네트워크의 RPC 노드 주소입니다.


FMZ와 이더리움을 사용하여 상호 작용

在部署好托管者程序、配置好交易所对象的前提下,就可以使用FMZ.COM的「调试工具」进行测试了。调用以太坊RPC方法和以太坊交互,除了本章节列举介绍的几个RPC方法,其它RPC方法可以查询资料了解,例如https://www.quicknode.com/docs

우리는 몇 가지 간단한 예제를 소개하고 기본부터 시작합니다. 다양한 언어와 도구에 대해 웹3에 접근할 수 있는 방법이 있습니다.

img

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_getBalance에테리움 주소에 있는 ETH 잔액을 검색하는 방법. 이 방법은 2개의 매개 변수를 입력해야 한다.

  • 이 글은 이쪽의 문서를 통해 공개되었습니다.
  • 이 문서는 "최근"을 사용하는 태그를 가리키고 있습니다.

에테리움의 창업자를 찾아보죠.V神ETH 지갑의 주소는 다음과 같습니다.0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045

function main() {
    let ethBalance = exchange.IO("api", "eth", "eth_getBalance", "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "latest")
    Log("ethBalance:", ethBalance)
}

관리자를 배포하고 거래소 객체를 구성하고 있으며, 디뷰팅 도구에서 코드를 테스트합니다.

img

이 코드를 실행하기 위해 실행 버튼을 누르면 다음과 같은 결과를 볼 수 있습니다.

eth평형: 0x117296558f185bbc4c6

Log이 함수들은ethBalance변수 값은:0x117296558f185bbc4c6,는 문자열 타입입니다.16자리 기준의 ETH 잔액그리고wei이 모든 것은1e18 wei1입니다.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)
}

img

위쪽https://etherscan.io/질문:

img

그러나 언어 자체의 정확성에 대한 문제로 인해 오류가 발생할 수 있기 때문에 FMZ 플랫폼은 데이터를 처리하기 위해 두 가지 기능을 내장했습니다.

  • Big:Int는 BigInt 객체로 16진트 문자열을 변환합니다.
  • BigDecimal: 숫자 타입의 객체를 계산 가능한 BigDecimal 객체로 변환한다.

코드를 다시 조정합니다:

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

eth_chainId그리고net_version이 두 함수는 현재 RPC 노트 접속된 블록 체인의 Id를 반환합니다.net_version10분의 1의 10분의 1의 10분의 1의 10분의 1의eth_chainId16개 계열의 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

img

에테리움 테스트 네트워크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))
}

img

eth_gasPrice

전화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

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))
}

디뷰팅 도구에서 실행:

img

https://etherscan.io/이 문서를 검색하세요:

img

eth_getBlockByNumber

이 블로그의 내용은 다음과 같습니다:

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])
    }
}

"디맥업 도구"에서 실행하면 다음과 같은 정보를 얻을 수 있습니다.

img


계약 정보를 읽습니다.

에테리움에는 수많은 스마트 컨트랙트 애플리케이션이 운영되고 있습니다.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이봐요

ABI,即应用程序二进制接口(Application Binary Interface),是智能合约与外部世界进行通信的接口标准。
智能合约的 ABI 定义了合约的函数接口、参数类型、返回值等信息,以及调用合约的方式和参数传递方式等规范。

智能合约的 ABI 通常以 JSON 格式存储,包含以下信息:

合约的函数接口:函数名、参数列表、返回值等信息。
函数参数类型:如 uint256、bool、string 等。
函数的输入参数和输出参数的编码方式:智能合约使用一种称为 Solidity ABI 的编码方式来编码函数的输入参数和输出参数,
以便与以太坊网络进行交互。
在以太坊网络中,使用智能合约的 ABI 来调用合约的函数。当需要调用合约函数时,需要提供函数名和函数参数,以及将函数参数按照 ABI 编码方式编码后的字节码。
以太坊节点会将这些信息打包成一笔交易,并将交易发送到以太坊网络中执行。

智能合约的 ABI 在 Solidity 语言中可以通过 interface 关键字来定义。以太坊开发工具如 Remix IDE、Truffle 等也提供了 ABI 编辑和生成工具,
使得开发者可以方便地创建和使用智能合约的 ABI。

이 자료를 가져와서resolverABI를 사용할 수 있습니다.https://etherscan.io/계약에 대한 ABI를 검색하거나 다른 방법으로 ABI를 얻을 수 있습니다 (예: 관련 프로젝트 문서).

img

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계약의 주소는.

img

let resolverAddress = exchange.IO("api", "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", "resolver", ensNode)

사용ENS: Public Resolver계약addrV의 지갑 주소를 얻는 방법.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)

img

마지막 전화ENS: Public Resolver계약addr그 방법, 그 매개 변수는 여전히ensNode

let vitalikAddress = exchange.IO("api", resolverAddress, "addr", ensNode)
Log("vitalikAddress:", vitalikAddress)

로그 함수 출력:

img

vitalikAddress: 0xd8da6bf26964af9d7eed9e03e53415d37aa96045

ENS를 호출하는 전체 코드

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)
}

ETH 전송

이전 강의에서 우리는 개인 키를 구성하는 방법을 배웠습니다. 개인 키가 해당 지갑 주소인지 어떻게 알 수 있을까요?exchange.IO("address")함수는 설정된 개인 키에 해당하는 지갑 주소를 얻습니다.

이 장의 다음의 내용이 사용됨에 따라Goerli그래서 제가 사용하는 노드는 다음과 같습니다.https://goerli.infura.io/v3/*******인푸라는 등록된 사용자마다 다른 노드 주소를 할당합니다.*******이 글은 멘토의 글입니다.

function main() {
    let walletAddress = exchange.IO("address")
    Log("测试网 goerli 钱包地址:", walletAddress)
}

img

자금 지갑 주소를 알고 나면 Ethereum의 RPC 방법을 사용할 수 있습니다.eth_getTransactionCount지갑 주소를 검색하는 거래 수. 이 트랜잭션 수는 이더리움에서 매우 자주 사용되며, 실제로는 송금 작업에 입력되어야합니다.nonce매개 변수, 에테리움에서, nonce는 각 거래가 고유한 숫자임을 확인하기 위해 사용된다. 그것은 증가하는 숫자이며, 새로운 거래가 전송될 때마다 자동으로 증가한다. 따라서, 당신이 스마트 계약에 거래를 전송할 때, 거래가 독특하고 순서가 올바르다는 것을 확인하기 위해 nonce를 제공해야 한다.

https://goethereumbook.org/en/

img

여기 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 유닛이다.

알겠습니다.noncegasPricegasLimit이 개념들은 전송을 테스트 할 수 있습니다. FMZ에 포장된 매우 간단하고 사용하기 쉬운 전송 함수.

exchange.IO("api", "eth", "send", toAddress, toAmount)

이 글은 유저들의 관심과 관심의 대상이 되었습니다.exchange.IO이 문서는 "Send"이라는 문자로 작성된 것입니다.toAddress이 매개 변수는 트랜스포먼트 시 ETH를 수신하는 주소입니다.toAmount트랜스포팅에 필요한 ETH의 양.

noncegasPricegasLimit이 매개 변수는 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

img

또한 코드 쿼리 전송 해시를 작성할 수 있습니다.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 계약 (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", linkAddre

더 많은