0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

USDTのコントラクトを呼ぶ

Posted at

はじめに(Introduction)

前回、USDTのコントラクトを読んでみました。
ERC20の他に以下の機能を有していることがわかりました。

  • 認証(Ownable)
  • 手数料(Fee)
  • 一時停止(Pausable)
  • アップグレード(Upgrade)
  • ブラックリスト(BlackList)
  • 発行(Issue)/ 償還(Redeem)

実際にどのような状況であるかをブロックチェーンから呼び出してみたいと思います。

準備

コントラクトアドレスは0xdAC17F958D2ee523a2206206994597C13D831ec7です。
コントラクトが作成された、トランザクションハッシュは0x2f1c5c2b44f771e942a8506148e256f94f1a464babc938ae0690c6e34cd79190です。
生成されたブロックは4634748です。

RPCのエンドポイントは以下を使用します。

const { ethers } = require("ethers");

const USDT_ABI = [
    // https://ethereum.org/ja/developers/docs/standards/tokens/erc-20/
    'function name() public view returns (string)',
    'function symbol() public view returns (string)',
    'function decimals() public view returns (uint8)',
    'function totalSupply() public view returns (uint256)',
    'function balanceOf(address _owner) public view returns (uint256 balance)',
    'function transfer(address _to, uint256 _value) public returns (bool success)',
    'function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)',
    'function approve(address _spender, uint256 _value) public returns (bool success)',
    'function allowance(address _owner, address _spender) public view returns (uint256 remaining)',
    'event Transfer(address indexed _from, address indexed _to, uint256 _value)',
    'event Approval(address indexed _owner, address indexed _spender, uint256 _value)',
    // Ownable
    'function owner() public view returns (address)',
    // fee
    'function basisPointsRate() public view returns (uint256)',
    'function maximumFee() public view returns (uint256)',
    'event Params(uint feeBasisPoints, uint maxFee)',
    // Pausable
    'function paused() public view returns (bool)',
    'event Pause()',
    'event Unpause()',
    // upgrade
    'function deprecated() public view returns (bool)',
    'event Deprecate(address newAddress)',
    // BlackList
    'function getBlackListStatus(address _maker) public view returns (bool)',
    'event DestroyedBlackFunds(address _blackListedUser, uint _balance)',
    'event AddedBlackList(address _user)',
    'event RemovedBlackList(address _user)',
    // Issue
    'event Issue(uint amount)',
    // Redeem
    'event Redeem(uint amount)',
];

// https://www.publicnode.com/
const ETHEREUM_RPC_ENDPOINT = 'https://ethereum-rpc.publicnode.com';
const MAX_BLOCK_RANGE = 50000;

// https://etherscan.io/tx/0x2f1c5c2b44f771e942a8506148e256f94f1a464babc938ae0690c6e34cd79190
const TETHER_TOKEN_ADDRES = '0xdAC17F958D2ee523a2206206994597C13D831ec7';
const CREATE_BLOCK_NUMBER = 4634748;

async function main() {
    const provider = new ethers.JsonRpcProvider(ETHEREUM_RPC_ENDPOINT);
    const tether = new ethers.Contract(TETHER_TOKEN_ADDRES, USDT_ABI, provider);
    const blockNumber = await provider.getBlockNumber();
    console.log(`blockNumber     : ${blockNumber}`);

    // ここにコードを記述します。

}

main().then(() => {
    process.exit(0);
}).catch((error) => {
    console.error(error);
    process.exit(1);
});

ERC20

ERC20の基本的な情報を見てみます。

    // ERC20
    const name = await tether.name();
    const symbol = await tether.symbol();
    const decimals = await tether.decimals();
    const totalSupply = await tether.totalSupply();
    console.log(`name            : ${name}`);
    console.log(`symbol          : ${symbol}`);
    console.log(`decimals        : ${decimals}`);
    console.log(`totalSupply     : ${ethers.formatUnits(totalSupply, decimals)}`);

結果は以下のとおりです。

blockNumber     : 20939907
name            : Tether USD
symbol          : USDT
decimals        : 6
totalSupply     : 54966490253.66394

54,966,490,253 USDT!?すごいですね、日本円して8兆円規模のトークンのようです。
コントラクトの作成時は、100 USDTだったのでかなりの規模に成長しているようです。

認証(Ownable)

現在のownerを見てみます。
また、現在USDTをどのくらい持っているかも見てみます。

    // Ownable
    const owner = await tether.owner();
    const balanceOf = await tether.balanceOf(owner);
    console.log(`owner           : ${owner}`);
    console.log(`balanceOf       : ${ethers.formatUnits(balanceOf, decimals)}`);

結果は以下のとおりです。

blockNumber     : 20940260
owner           : 0xC6CDE7C39eB2f0F0095F41570af89eFC2C1Ea828
balanceOf       : 108983.76699

現在のowner0xC6CDE7C39eB2f0F0095F41570af89eFC2C1Ea828だそうです。
EthscanによればMultiSigWalletだそうです。
コントラクトの作成とは異なるので、transferOwnershipを利用して変更しています。

手数料(Fee)

現在の手数料関連のパラメータを見てみます。

    // Fee
    const basisPointsRate = await tether.basisPointsRate();
    const maximumFee = await tether.maximumFee();
    console.log(`basisPointsRate : ${basisPointsRate}`);
    console.log(`maximumFee      : ${maximumFee}`);

結果は以下のとおりです。

blockNumber     : 20940460
basisPointsRate : 0
maximumFee      : 0

手数料は設定されていないようです。
イベント検索でパラメータ設定時に発行されるParamsイベントを検索してみましたが検出できなかったので、手数料が発生していることはいままでに一度もなさそうです。

一時停止(Pausable)

一時停止の状況を取得します。

    // Pausable
    const paused = await tether.paused();
    console.log(`paused          : ${paused}`);

結果は以下のとおりです。

blockNumber     : 20940586
paused          : false

現在稼働中のトークンなので停止していることはないです。
イベント検索でPauseUnpauseを検索してみたところ検出されませんでした、停止されたことは今までに一度もなさそうです。

アップグレード(Upgrade)

アップグレードされているかを見てみます。

    // Upgrade
    const deprecated = await tether.deprecated();
    console.log(`deprecated      : ${deprecated}`);

結果は以下のとおりです。

blockNumber     : 20940787
deprecated      : false

アップグレードされていないようです。
deprecatedtrueに変更するとコード的にはfalseに変更することはできないため、今までに一度もアップグレードはされていないようです。
Deprecateイベントも検出されませんでした。

ブラックリスト(BlackList)

ブロック番号20940838の時点でのイベントを収集してみます。
イベントAddedBlackListは、ブラックリストへ追加した時に発生するイベントです。
イベントDestroyedBlackFundsは、ブラックリストに入っているアドレスの資産を破棄した時に発生するイベントです。
イベントRemovedBlackListは、ブラックリストから除外する時に発生するイベントです。

イベントの回数は以下のとおりです。

イベント名 回数 総量
AddedBlackList 1,828 -
DestroyedBlackFunds 853 243,627,751.978060
RemovedBlackList 66 -

これらの操作はownerだけが出来る操作です。

発行(Issue)/ 償還(Redeem)

ブロック番号20940978の時点でのイベントを収集してみます。
イベントIssueは、USDTを発行した時に発生するイベントです。
イベントRedeemは、USDTを償還した時に発生するイベントです。

イベント名 回数 総量
Issue 180 64,710,018,005.642000
Redeem 3 9,500,000,000.000000

これらの操作はownerだけが出来る操作です。

まとめ(Conclusion)

USDT(Tether)は、7年前から運用されている老舗のトークンですが今では販売所などで取引できるトークンです。
トークンに必要な機能も備えているようです。
手数料や一時停止、アップグレードなどの機能は使われていないようですが、機能として想定していることがわかりました。
今後発行されるERC20の参考となると思います。

補足(Appendix)

イベント検索(Search Event)

対象のイベントにあるコメントを外して使用してください。

    console.log('CREATE_BLOCK_NUMBER', CREATE_BLOCK_NUMBER, 'blockNumber', blockNumber);
    let eventFilter = [[]];
    // Pause
    // eventFilter[0] = eventFilter[0].concat(await tether.filters.Pause().getTopicFilter());
    // eventFilter[0] = eventFilter[0].concat(await tether.filters.Unpause().getTopicFilter());
    // Fee
    // eventFilter[0] = eventFilter[0].concat(await tether.filters.Params().getTopicFilter());
    // Update
    // eventFilter[0] = eventFilter[0].concat(await tether.filters.Deprecate().getTopicFilter());
    // BlackList
    // eventFilter[0] = eventFilter[0].concat(await tether.filters.DestroyedBlackFunds().getTopicFilter());
    // eventFilter[0] = eventFilter[0].concat(await tether.filters.AddedBlackList().getTopicFilter());
    // eventFilter[0] = eventFilter[0].concat(await tether.filters.RemovedBlackList().getTopicFilter());
    // Issue / Redeem
    // eventFilter[0] = eventFilter[0].concat(await tether.filters.Issue().getTopicFilter());
    // eventFilter[0] = eventFilter[0].concat(await tether.filters.Redeem().getTopicFilter());
    if (eventFilter[0].length > 0) {
        let eventCount = 0;
        for (let i = CREATE_BLOCK_NUMBER; i < blockNumber; i += MAX_BLOCK_RANGE + 1) {
            const from = i;
            const to = from + MAX_BLOCK_RANGE < blockNumber ? from + MAX_BLOCK_RANGE : blockNumber;
            console.log('queryFilter', from, to);
            const logs = await tether.queryFilter(eventFilter, from, to);
            if (logs.length > 0) {
                for (let log of logs) {
                    console.log('event', log.transactionHash, log.fragment.name, log.args.join(' '));
                }
                eventCount += logs.length;
            }
        }
        console.log('event count :', eventCount);
    }

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?