

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# Amazon Managed Blockchain (AMB) 查詢入門
<a name="getting-started"></a>

使用本節中的step-by-step教學課程，了解如何使用 Amazon Managed Blockchain (AMB) 查詢執行任務。這些程序需要一些先決條件。如果您是初次使用 AMB 查詢，您可以檢閱本指南*的設定*一節。如需詳細資訊，請參閱[設定 Amazon Managed Blockchain (AMB) 查詢](ambq-setting-up.md)。

**注意**  
這些範例中的某些變數已刻意混淆。在執行這些範例之前，將它們替換為您自己的有效範例。

**Topics**
+ [建立 IAM 政策以存取 AMB Query API 操作](#getting-started-iam-policy)
+ [使用 Go 提出 Amazon Managed Blockchain (AMB) 查詢 API 請求](#getting-started-go-example)
+ [使用 Node.js 提出 Amazon Managed Blockchain (AMB) 查詢 API 請求](#node-amb-query-requests)
+ [使用 Python 提出 Amazon Managed Blockchain (AMB) 查詢 API 請求](#python-amb-query-requests)
+ [在 上使用 Amazon Managed Blockchain (AMB) 查詢 AWS 管理主控台 來執行 GetTokenBalance 操作](#query-console-gettokenbalance-example)

## 建立 IAM 政策以存取 AMB Query API 操作
<a name="getting-started-iam-policy"></a>

若要提出 AMB Query API 請求，您必須使用具有 Amazon Managed Blockchain (AWS\_ACCESS\_KEY\_ID 和 AWS\_SECRET\_ACCESS\_KEY)。在 AWS CLI 已安裝 的終端機中，執行下列命令來建立 IAM 政策以存取 AMB Query API 操作：

```
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 服務，並將政策連接至指派給將使用服務的 IAM 使用者`AmazonManagedBlockchainQueryAccess`的角色。如需詳細資訊，請參閱[建立角色並指派給 IAM 使用者](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user.html)。

**注意**  
AWS 建議您授予特定 API 操作的存取權，而不是使用萬用字元 `*`。如需詳細資訊，請參閱[存取特定 Amazon Managed Blockchain (AMB) 查詢 API 動作](security_iam_id-based-policy-examples.md#security_iam_id-based-policy-examples-access-ambquery-apis)。

## 使用 Go 提出 Amazon Managed Blockchain (AMB) 查詢 API 請求
<a name="getting-started-go-example"></a>

透過 Amazon Managed Blockchain (AMB) 查詢，您可以在區塊鏈上確認區塊鏈資料後，建立依賴即時存取的應用程式，即使尚未達到*最終版本*。AMB Query 啟用數個使用案例，例如填入錢包的交易歷史記錄、根據交易雜湊提供交易的相關內容資訊，或取得原生字符以及 ERC-721, ERC-1155和 ERC-20 字符的平衡。

下列範例是以 Go 語言建立，並使用 AMB Query API 操作。如需 Go 的詳細資訊，請參閱 [Go 文件](https://go.dev/doc/)。如需 AMB 查詢 API 的詳細資訊，請參閱 [Amazon Managed Blockchain (AMB) 查詢 API 參考文件](https://docs.aws.amazon.com/managed-blockchain/latest/AMBQ-APIReference/API_Operations.html)。

下列範例使用 `ListTransactions`和 `GetTransaction` API 動作，先取得 Ethereum Mainnet 上指定外部擁有地址 (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 在 Ethereum Mainnet 上取得地址 Ether (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 提出 Amazon Managed Blockchain (AMB) 查詢 API 請求
<a name="node-amb-query-requests"></a>

若要執行這些節點範例，適用下列先決條件：

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 提交已簽署的請求，以存取 Amazon Managed Blockchain (AMB) 查詢 API 操作，並使用 [ Node.js 中的原生 https 模組](https://nodejs.org/api/https.html)提出請求，或者您可以使用第三方程式庫，例如 [AXIOS](https://www.npmjs.com/package/axios) 並從 AMB Query 擷取資料。
這些範例使用 Node.js 的第三方 HTTP 用戶端，但您也可以使用 AWS JavaScript 開發套件向 AMB 查詢提出請求。
下列範例說明如何使用 Axios 和 AWS SigV4 的 SDK 模組提出 AMB Query 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 Query `GetTokenBalance` API 從特定外部擁有的地址 (EOA) 擷取歷史字符餘額**  
您可以使用 `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 在 Ethereum Mainnet 上取得 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
```
 此命令會執行指令碼，傳入程式碼中定義的引數，以請求 Ethereum Mainnet 上所列 EOA 的 ERC20 USDC 平衡。回應類似如下：  

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

## 使用 Python 提出 Amazon Managed Blockchain (AMB) 查詢 API 請求
<a name="python-amb-query-requests"></a>

若要執行這些 Python 範例，適用下列先決條件：

1. 您必須在機器上安裝 Python。您可以在[此處](https://wiki.python.org/moin/BeginnersGuide/Download)找到作業系統的安裝指示。

1. 安裝[適用於 Python (Boto3) 的 AWS 開發套件。 ](https://aws.amazon.com/sdk-for-python/)

1. 安裝 [AWS Command Line Interface](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) 並執行 命令`aws configure`來設定 `Access Key ID`、 `Secret Access Key`和 的變數`Region`。

完成所有先決條件之後，您可以透過 HTTPS 使用適用於 Python 的 AWS SDK 提出 Amazon Managed Blockchain (AMB) 查詢 API 請求。

下列 Python 範例使用來自 boto3 的模組，將附加必要 SigV4 標頭的請求傳送至 AMB Query `ListTransactionEvents` API 操作。此範例會擷取 Ethereum Mainnet 上指定交易發出的事件清單。

將下列`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`。此命令會執行指令碼，傳入程式碼中定義的引數，以請求與 Ethereum Mainnet 上指定交易雜湊相關聯的事件。回應類似如下：

```
{
 '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>

下列範例示範如何在 *Ethereum Mainnet* 上使用 上的 Amazon Managed Blockchain (AMB) 查詢取得權杖的餘額 AWS 管理主控台

**Example**  

1. 開啟位於 https：//[https://console.aws.amazon.com/managedblockchain/](https://console.aws.amazon.com/managedblockchain/) 的 Amazon Managed Blockchain 主控台。

1. 從**查詢區段中選擇查詢編輯器**。 ** **

1. 選擇 **ETHEREUM\_MAINNET** 做為**區塊鏈網路**。

1. 選擇 **GetTokenBalance** 做為**查詢類型**。

1. 輸入字符的**區塊鏈地址**。

1. 輸入字符的**合約地址**。

1. 輸入權**杖的選用權杖 ID**。

1. 選擇**權杖餘額的日期**。

1. 輸入權杖餘額的選用**時間點**。

1. 選擇 **Run query** (執行查詢)。
AMB Query 將執行您的查詢，您會在**查詢結果**視窗中看到結果。