

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 亚马逊托管区块链 (AMB) 查询入门
<a name="getting-started"></a>

使用本节中的 step-by-step教程来学习如何使用亚马逊托管区块链 (AMB) 查询来执行任务。这些过程需要一些先决条件。如果您不熟悉 AMB Query，可以查看本指南的*设置*部分。有关更多信息，请参阅 [设置亚马逊托管区块链 (AMB) 查询](ambq-setting-up.md)。

**注意**  
这些示例中的一些变量是故意混淆的。在运行这些示例之前，请将它们替换为您自己的有效版本。

**Topics**
+ [创建用于访问 AMB 查询 API 操作的 IAM 策略](#getting-started-iam-policy)
+ [使用 Go 发出亚马逊托管区块链 (AMB) 查询 API 请求](#getting-started-go-example)
+ [使用 Node.js 发出亚马逊托管区块链 (AMB) 查询 API 请求](#node-amb-query-requests)
+ [使用 Python 发出亚马逊托管区块链 (AMB) 查询 API 请求](#python-amb-query-requests)
+ [使用上的 Amazon Managed Blockchain (AMB) 查询 AWS 管理控制台 来运行操作 GetTokenBalance](#query-console-gettokenbalance-example)

## 创建用于访问 AMB 查询 API 操作的 IAM 策略
<a name="getting-started-iam-policy"></a>

要发出 AMB 查询 API 请求，您必须使用对亚马逊托管区块链 (AMB) 查询具有相应 IAM 权限的用户证书（AWS\_ACCESS\_KEY\_ID 和 AWS\_SECRET \_ACCESS\_KEY）。在 AWS CLI 安装了的终端中，运行以下命令创建用于访问 AMB Query API 操作的 IAM 策略：

```
cat <<EOT > ~/{{amb-query-access-policy.json}}
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid" : "{{AMBQueryAccessPolicy}}",
            "Effect": "Allow",
            "Action": [
                "managedblockchain-query:*"
            ],
            "Resource": "*"
        }
    ]
}
EOT
aws iam create-policy --policy-name AmazonManagedBlockchainQueryAccess --policy-document {{file://$HOME/amb-query-access-policy.json}}
```

创建策略后，将该策略附加到 IAM 用户的角色以使其生效。在中 AWS 管理控制台，导航到 IAM 服务，并将策略附加`AmazonManagedBlockchainQueryAccess`到分配给将使用该服务的 IAM 用户的角色。有关更多信息，请参阅[创建角色并分配给 IAM 用户](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user.html)。

**注意**  
AWS 建议您授予对特定 API 操作的访问权限，而不是使用通配符。`*`有关更多信息，请参阅 [访问特定的亚马逊托管区块链 (AMB) 查询 API 操作](security_iam_id-based-policy-examples.md#security_iam_id-based-policy-examples-access-ambquery-apis)。

## 使用 Go 发出亚马逊托管区块链 (AMB) 查询 API 请求
<a name="getting-started-go-example"></a>

借助 Amazon Managed Blockchain (AMB) 查询，即使区块链数据尚未*最终*确定，您也可以构建依赖于即时访问区块链数据的应用程序。AMB Query 支持多种用例，例如填充钱包的交易历史记录、根据交易哈希提供有关交易的上下文信息，或者获取原生代币以及 ERC-721、ERC-1155 和 ERC-20 代币的余额。

以下示例使用 Go 语言创建，并使用 AMB 查询 API 操作。有关 Go 的更多信息，请参阅 [Go 文档](https://go.dev/doc/)。有关 AMB 查询 API 的更多信息，请参阅[亚马逊托管区块链 (AMB) 查询 API 参考文档](https://docs.aws.amazon.com/managed-blockchain/latest/AMBQ-APIReference/API_Operations.html)。

以下示例使用`ListTransactions`和 `GetTransaction` API 操作首先获取以太坊主网上给定外部拥有地址 (EOA) 的所有交易的列表，然后下一个示例从列表中检索单笔交易的交易详细信息。

**Example — 使用 Go 进行 `ListTransactions` API 操作**  
将以下代码复制到*ListTransactions*目录`listTransactions.go`中名为的文件中。  

```
package main

import (
    "fmt"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/managedblockchainquery"
    "time"
)

func main() {

    // Set up a session
    ambQuerySession := session.Must(session.NewSessionWithOptions(session.Options{
        Config: aws.Config{
            Region: aws.String("{{us-east-1}}"),
        },
    }))
    client := managedblockchainquery.New(ambQuerySession)

    // Inputs for ListTransactions API
    ownerAddress := "{{0x00000bf26964af9d7eed9e03e53415d********}}"
    network := managedblockchainquery.{{QueryNetworkEthereumMainnet}}
    sortOrder := managedblockchainquery.{{SortOrderAscending}}
    fromTime := time.{{Date(1971, 1, 1, 1, 1, 1, 1, time.UTC)}}
    toTime := {{time.Now()}}
    nonFinal := "{{NONFINAL}}"
    // Call ListTransactions API. Transactions that have reached finality are always returned
    listTransactionRequest, listTransactionResponse := client.ListTransactionsRequest(&managedblockchainquery.ListTransactionsInput{
        Address: &ownerAddress,
        Network: &network,
        Sort: &managedblockchainquery.ListTransactionsSort{
            SortOrder: &sortOrder,
        },
        FromBlockchainInstant: &managedblockchainquery.BlockchainInstant{
            Time: &fromTime,
        },
        ToBlockchainInstant: &managedblockchainquery.BlockchainInstant{
            Time: &toTime,
        },
        
        ConfirmationStatusFilter: &managedblockchainquery.ConfirmationStatusFilter{
            Include: []*string{&nonFinal},
          },
    })
    errors := listTransactionRequest.Send()

    if errors == nil {
        // handle API response
        fmt.Println(listTransactionResponse)
    } else {
        // handle API errors
        fmt.Println(errors)
    }
}
```

保存文件后，在*ListTransactions*目录中使用以下命令运行代码：`go run listTransactions.go`。

以下输出类似于以下内容：

```
{
  Transactions: [
    {
      ConfirmationStatus: "FINAL",
      Network: "ETHEREUM_MAINNET",
      TransactionHash: "0x12345ea404b45323c0cf458ac755ecc45985fbf2b18e2996af3c8e8693354321",
      TransactionTimestamp: 2020-06-01 01:59:11 +0000 UTC
    },
    {
      ConfirmationStatus: "FINAL",
      Network: "ETHEREUM_MAINNET",
      TransactionHash: "0x1234547c65675d867ebd2935bb7ebe0996e9ec8e432a579a4516c7113bf54321",
      TransactionTimestamp: 2021-09-01 20:06:59 +0000 UTC
    },
     {
      ConfirmationStatus: "NONFINAL",
      Network: "ETHEREUM_MAINNET",
      TransactionHash: "0x123459df7c1cd42336cd1c444cae0eb660ccf13ef3a159f05061232a24954321",
      TransactionTimestamp: 2024-01-23 17:10:11 +0000 UTC
    }
  ]
}
```

**Example — 使用 Go 进行 `GetTransaction` API 操作**  
此示例使用先前输出中的交易哈希。将以下代码复制到*GetTransaction*目录`GetTransaction.go`中名为的文件中。  

```
package main

import (
    "fmt"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/managedblockchainquery"
)

func main() {

    // Set up a session
    ambQuerySession := session.Must(session.NewSessionWithOptions(session.Options{
        Config: aws.Config{
            Region: aws.String("us-east-1"),
        },
    }))
    client := managedblockchainquery.New(ambQuerySession)

    // inputs for GetTransaction API
    transactionHash := "{{0x123452695a82868950d9db8f64dfb2f6f0ad79284a6c461d115ede8930754321}}"
    network := managedblockchainquery.{{QueryNetworkEthereumMainnet}}

    // Call GetTransaction API. This operation will return transaction details for all 
    // transactions that are conﬁrmed on the blockchain, even if they have not 
    // reached ﬁnality.
    getTransactionRequest, getTransactionResponse := client.GetTransactionRequest(&managedblockchainquery.{{GetTransactionInput}}{
        Network:         &network,
        TransactionHash: &transactionHash,
    })

    errors := getTransactionRequest.Send()
    if errors == nil {
        // handle API response
        fmt.Println({{getTransactionResponse}})
    } else {
        // handle API errors
        fmt.Println(errors)
    }
}
```
保存文件后，在*GetTransaction*目录中使用以下命令运行代码：`go run GetTransaction.go`。  
以下输出类似于以下内容：  

```
{
  Transaction: {
    BlockHash: "0x000005c6a71d1afbc005a652b6ceca71cd516d97b0fc514c2a1d0f2ca3912345",
    BlockNumber: "11111111",
    CumulativeGasUsed: "5555555",
    EffectiveGasPrice: "44444444444",
    From: "0x9157f4de39ab4c657ad22b9f19997536********",
    GasUsed: "22222",
    Network: "ETHEREUM_MAINNET",
    NumberOfTransactions: 111,
    SignatureR: "0x99999894fd2df2d039b3555dab80df66753f84be475069dfaf6c6103********",
    SignatureS: "0x77777a101e7f37dd2dd0bf878b39080d5ecf3bf082c9bd4f40de783e********",
    SignatureV: 0,
    ConfirmationStatus: "FINAL", 
    ExecutionStatus: "SUCCEEDED", 
    To: "0x5555564f282bf135d62168c1e513280d********",
    TransactionHash: "0x123452695a82868950d9db8f64dfb2f6f0ad79284a6c461d115ede8930754321",
    TransactionIndex: 11,
    TransactionTimestamp: 2022-02-02 01:01:59 +0000 UTC
  }
}
```

该 `GetTokenBalance` API为您提供了一种获取原生代币（ETH和BTC）余额的方法，该余额可用于获取某个时间点外部拥有的账户（EOA）的当前余额。

**Example — 使用 `GetTokenBalance` API 操作获取 Go 中原生代币的余额**  
在以下示例中，您使用 `GetTokenBalance` API 在以太坊主网上获取地址以太坊 (ETH) 余额。将以下代码复制到*GetTokenBalance*目录`GetTokenBalanceEth.go`中名为的文件中。  

```
package main

import (
    "fmt"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/managedblockchainquery"
)

func main() {
    // Set up a session
    ambQuerySession := session.Must(session.NewSessionWithOptions(session.Options{
        Config: aws.Config{
            Region: aws.String("us-east-1"),
        },
    }))
    client := managedblockchainquery.New(ambQuerySession)

    // inputs for GetTokenBalance API
    ownerAddress := "{{0xBeE510AF9804F3B459C0419826b6f225********}}"
    network := managedblockchainquery.{{QueryNetworkEthereumMainnet}}
    nativeTokenId  := "{{eth}}" //Ether on Ethereum mainnet

    // call GetTokenBalance API
    getTokenBalanceRequest, getTokenBalanceResponse := client.GetTokenBalanceRequest(&managedblockchainquery.{{GetTokenBalanceInput}}{
        TokenIdentifier: &managedblockchainquery.TokenIdentifier{
            Network:         &network,
            TokenId: &nativeTokenId,
        },
        OwnerIdentifier: &managedblockchainquery.OwnerIdentifier{
            Address: &ownerAddress,
        },
    })
    errors := getTokenBalanceRequest.Send()

    if errors == nil {
        // process API response
        fmt.Println(getTokenBalanceResponse)
    } else {
        // process API errors
        fmt.Println(errors)
    }
}
```
保存文件后，在*GetTokenBalance*目录中使用以下命令运行代码：`go run GetTokenBalanceEth.go`。  
以下输出类似于以下内容：  

```
{
  AtBlockchainInstant: {
    Time: 2020-12-05 11:51:01 +0000 UTC
  },
  Balance: "4343260710",
  LastTransactionHash: "0x00000ce94398e56641888f94a7d586d51664eb9271bf2b3c48297a50a0711111",
  LastTransactionTime: 2023-03-14 18:33:59 +0000 UTC,
  OwnerIdentifier: {
    Address: "0x12345d31750D727E6A3a7B534255BADd********"
  },
  TokenIdentifier: {
    Network: "ETHEREUM_MAINNET",
    TokenId: "eth"
  }
}
```

## 使用 Node.js 发出亚马逊托管区块链 (AMB) 查询 API 请求
<a name="node-amb-query-requests"></a>

要运行这些 Node 示例，需要满足以下先决条件：

1. 您的计算机上必须安装节点版本管理器 (nvm) 和 Node.js。您可以[在此处](https://github.com/nvm-sh/nvm)找到操作系统的安装说明。

1. 使用`node --version`命令并确认您使用的是 *Node 版本 14* 或更高版本。如果需要，您可以使用`nvm install 14`命令和`nvm use 14`命令安装*版本 14*。

1. 环境变量`AWS_ACCESS_KEY_ID`和`AWS_SECRET_ACCESS_KEY`必须包含与账户关联的凭证。

   使用以下命令将这些变量作为字符串导出到客户端。将以下突出显示的值替换为 IAM 用户账户中的相应值。

   ```
   export AWS_ACCESS_KEY_ID="{{AKIAIOSFODNN7EXAMPLE}}"
   export AWS_SECRET_ACCESS_KEY="{{wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY}}"
   ```

**注意**  
完成所有先决条件后，您可以通过 HTTPS 提交签名的请求以访问亚马逊托管区块链 (AMB) 查询 API 操作并使用 [Node.js 中的原生 https 模块](https://nodejs.org/api/https.html)提出请求，也可以使用 [AXIO](https://www.npmjs.com/package/axios) S 等第三方库并从 AMB 查询中检索数据。
这些示例使用第三方 HTTP 客户端 Node.js，但您也可以使用 AWS JavaScript 软件开发工具包向 AMB Query 发出请求。
以下示例向您展示了如何使用 Axios 和 Sigv4 的 AWS SDK 模块发出 AMB 查询 API 请求。

将以下`package.json`文件复制到本地环境的工作目录中：

```
{
  "name": "{{amb-query-examples}}",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@aws-crypto/sha256-js": "^4.0.0",
    "@aws-sdk/credential-provider-node": "^3.360.0",
    "@aws-sdk/protocol-http": "^3.357.0",
    "@aws-sdk/signature-v4": "^3.357.0",
    "axios": "^1.4.0"
  }
}
```

**Example — 使用 AMB 查询 API 从特定的外部所有地址 (EOA) 检索历史代币余额 `GetTokenBalance`**  
您可以使用 `GetTokenBalance` API 获取各种代币（例如 ERC20 ERC721、和 ERC1155）和原生币（例如，ETH 和 BTC）的余额，您可以使用这些余额根据历史`timestamp`（Unix 时间戳-秒）获取外部拥有的账户 (EOA) 的当前余额。在此示例中，您使用 [https://docs.aws.amazon.com/managed-blockchain/latest/AMBQ-APIReference/GetTokenBalance.html](https://docs.aws.amazon.com/managed-blockchain/latest/AMBQ-APIReference/GetTokenBalance.html)API 在以太坊主网上获取 ERC20 代币 USDC 的地址余额。  
要测试 `GetTokenBalance` API，请将以下代码复制到名为的文件中`token-balance.js`，然后将该文件保存到同一个工作目录中：  

```
const axios = require('axios').default;
const SHA256 = require('@aws-crypto/sha256-js').Sha256
const defaultProvider = require('@aws-sdk/credential-provider-node').defaultProvider
const HttpRequest = require('@aws-sdk/protocol-http').HttpRequest
const SignatureV4 = require('@aws-sdk/signature-v4').SignatureV4

// define a signer object with AWS service name, credentials, and region
const signer = new SignatureV4({
  credentials: defaultProvider(),
  service: 'managedblockchain-query',
  region: '{{us-east-1}}',
  sha256: SHA256,
});

const queryRequest = async (path, data) => {
  //query endpoint
  let queryEndpoint = `https://managedblockchain-query.{{us-east-1}}.amazonaws.com/${path}`;
  
  // parse the URL into its component parts (e.g. host, path)
  const url = new URL(queryEndpoint);
  
  // create an HTTP Request object
  const req = new HttpRequest({
    hostname: url.hostname.toString(),
    path: url.pathname.toString(),
    body: JSON.stringify(data),
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Accept-Encoding': 'gzip',
      host: url.hostname,
    }
  });

  
  // use AWS SignatureV4 utility to sign the request, extract headers and body
  const signedRequest = await signer.sign(req, { signingDate: new Date() });
  
  try {
    //make the request using axios
    const response = await axios({...signedRequest, url: queryEndpoint, data: data})

    console.log(response.data)
  } catch (error) {
    console.error('Something went wrong: ', error)
    throw error
  } 

 
}


let methodArg = 'get-token-balance';

let dataArg = {
  " atBlockchainInstant": {
    "time": {{1688071493}}
  },  
  "ownerIdentifier": {
      "address": "{{0xf3B0073E3a7F747C7A38B36B805247B2********}}" // externally owned address
  },
  "tokenIdentifier": {
      "contractAddress":"{{0xA0b86991c6218b36c1d19D4a2e9Eb0cE********}}", //USDC contract address 
      "network":"ETHEREUM_MAINNET"
  }
}

//Run the query request.
queryRequest(methodArg, dataArg);
```
要运行代码，请在文件所在目录下打开终端，然后运行以下命令：  

```
npm i
node token-balance.js
```
 此命令运行脚本，传入代码中定义的参数，以请求以太坊主网上列出的EOA的 ERC20 USDC余额。响应类似于以下内容：  

```
 {
  atBlockchainInstant: { time: 1688076218 },
  balance: '140386693440144',
  lastUpdatedTime: { time: 1688074727 },
  ownerIdentifier: { address: '0xf3b0073e3a7f747c7a38b36b805247b2********' },
  tokenIdentifier: {
    contractAddress: '0xa0b86991c6218b36c1d19d4a2e9eb0ce********',
    network: 'ETHEREUM_MAINNET'
  }
```

## 使用 Python 发出亚马逊托管区块链 (AMB) 查询 API 请求
<a name="python-amb-query-requests"></a>

要运行这些 Python 示例，需要满足以下先决条件：

1. 你的计算机上必须安装了 Python。您可以[在此处](https://wiki.python.org/moin/BeginnersGuide/Download)找到操作系统的安装说明。

1. 安装适用于 [Python 的 AWS 开发工具包 (Boto3](https://aws.amazon.com/sdk-for-python/))。

1. 安装[AWS 命令行界面](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)并运行命令`aws configure`为`Access Key ID``Secret Access Key`、和设置变量`Region`。

完成所有先决条件后，您可以通过 HTTPS 使用 AWS 适用于 Python 的软件开发工具包来发出亚马逊托管区块链 (AMB) 查询 API 请求。

以下 Python 示例使用 boto3 中的模块向 AMB 查询 API 操作发送附有必要 Sigv4 标头的请求。`ListTransactionEvents`此示例检索以太坊主网上给定交易发出的事件列表。

将以下`list-transaction-events.py`文件复制到本地环境的工作目录中：

```
import json
from botocore.auth import SigV4Auth
from botocore.awsrequest import AWSRequest
from botocore.session import Session
from botocore.httpsession import URLLib3Session

def signed_request(url, method,  params, service, region):

    session = Session()
    sigv4 = SigV4Auth(session.get_credentials(), service, region)
    data = json.dumps(params)
    request = AWSRequest(method, url, data=data)
    sigv4.add_auth(request)
    http_session = URLLib3Session()
    response = http_session.send(request.prepare())

    return(response)

url = 'https://managedblockchain-query.{{us-east-1}}.amazonaws.com/{{list-transaction-events}}'
method = 'POST'
params = {
'network': 'ETHEREUM_MAINNET', 
'transactionHash': '0x125714bb4db48757007fff2671b37637bbfd6d47b3a4757ebbd0c5222984f905'
}
service = 'managedblockchain-query'
region = '{{us-east-1}}'

# Call the listTransactionEvents operation. This operation will return transaction details for 
# all transactions that are conﬁrmed on the blockchain, even if they have not reached 
# ﬁnality.
listTransactionEvents = signed_request(url, method, params, service, region)

print(json.loads({{listTransactionEvents}}.content.decode('utf-8')))
```

要将示例代码运行到`ListTransactionEvents`，请将文件保存在工作目录中，然后运行该命令`python3 list-transaction-events.py`。此命令运行脚本，传入代码中定义的参数，以请求以太坊主网上与给定交易哈希相关的事件。响应类似于以下内容：

```
{
 'events': 
 [
  {
      'contractAddress': '0x95ad61b0a150d79219dcf64e1e6cc01f********',
      'eventType': 'ERC20_TRANSFER',
      'from': '0xab5801a7d398351b8be11c439e05c5b3********',
      'network': 'ETHEREUM_MAINNET',
      'to': '0xdead0000000000000000420694206942********',
      'transactionHash': '0x125714bb4db48757007fff2671b37637bbfd6d47b3a4757ebbd0c522********',
      'value': '410241996771871894771826174755464'
  }
 ]
}
```

## 使用上的 Amazon Managed Blockchain (AMB) 查询 AWS 管理控制台 来运行操作 GetTokenBalance
<a name="query-console-gettokenbalance-example"></a>

以下示例展示了如何使用亚马逊托管区块链 (AMB) 查询在*以太坊主网上*获取代币余额 AWS 管理控制台

**Example**  

1. 打开亚马逊区块链管理控制台，网址为[https://console.aws.amazon.com/managedblockchain/](https://console.aws.amazon.com/managedblockchain/)。

1. 从 “**查询” 部分中选择 “**查询**编辑器**”。

1. **选择**以太坊主网**作为区块链网络。**

1. 选择**GetTokenBalance**作为**查询类型**。

1. 输入代币的**区块链地址**。

1. 输入代币的**合约地址**。

1. 输入令**牌的可选令牌 ID**。

1. 选择代币余额的**截止日期**。

1. 为代币余额输入可选的 A **t tim** e。

1. 选择**运行查询**。
AMB Query 将运行您的查询，您将在**查询结果窗口中看到结果**。