ガスを費やすことなく財布のバランスにトークンをストリーミング


初めて聞いた時Proof of Humanity (Ethereumの上の人間のための社会的アイデンティティ検証システム)とそのUBIトークン(私の注意を捕えた)は、プロジェクトの慈善的な性質を除いて、プロジェクトが証明された人間に一般的な基本所得(UBI)トークンを分配するために非常に巧妙な技術を使用したということでした.このポストは、このプロジェクトに触発され、どのようにトークンがリアルタイムでガスを使用せずに他のアドレスにリアルタイムでストリーミングすることができますを説明することを目指しています.

典型的なトークン転送


通常のシナリオでは、erc 20標準を使用してトークンを割り当てることができますし、アドレスに転送します.フードの下で、この転送が実際にどのように行われるかは、アドレスがどのように多くのトークンを持っているかを追跡します.
mapping(address => uint256) private balances
このマッピングを編集すると、契約の状態が変更されます.
同じ標準に従って、バランスマップからの読み込みは、balanceOf(address account) 関数.読書は契約の状態を変更しないので、この関数呼び出しはcostlessになります.
これはトークン滴下/ストリーミングの背後にあるテクニックを理解するための鍵です.

トレーを財布に落とす


今、私たちは、トークンのX量を転送する必要があると言うことができます.以前に説明された規則的なアプローチを使用すると、これは定期的な転送を含みます.そして、それは各々の転送で定期的にガスを費やすことを含みます.
このシナリオは、我々は実際に経過時間を追跡することができますし、実際にどのように多くのトークンは、そのオンザフライでそのアドレスに属している計算することができますので、実際には、残高のマッピング(これにガスを費やすから私たちを保存)の上でそれを追跡せずにそのアドレスに属している.
しかし、ストリーミングはどこですか?
私たちは相互運用性を保証するためのインターフェースとしてerc 20標準を持っているので、我々は、我々が使用しているウォレットやソフトウェアの一部を呼び出すことに依存することができますbalanceOf 関数は、アドレスのバランスを取得します.
このケースでは、我々は時間の経過を追跡しながら、バランスのトークンの量をオンザフライで計算されているので、結果は(他の条件が適用されない場合)、アドレスのバランスでトークンの増加量です.簡単な例として、このポストの時に、メタメークチェックbalanceOf それぞれの20秒は、トークンのストリーミング/結果あなたの財布に、各20秒になります.
しかし、どのように我々は時間経過を追跡するのですか?
使用block.timestamp 実際に現在のブロックのUnixエポックにアクセスすることができますので、実際には時間差を追跡できます.これには次のようなコードがあります.
mapping(address => uint256) private startTime;

function register() public {
    startTime[msg.sender] = block.timestamp;
}

実施例


開始時刻が登録されると(上記のコードのように)、私たちのbalanceOf 財布で呼ばれる機能.私たちは、私たちがマッピングで私たちのアドレスを登録したときにブロックのタイムスタンプと現在のブロックのタイムスタンプの違いを計算することによってそれをすることができます、そして、我々が時間単位で割り当てたいX量のトークンのためにその違いを掛けます.
以下は、時間依存の方法の迅速であるが、作業例ですbalanceOf 関数を実行できます.
uint256 private tokenPerSecond = 1;

function isRegistered(address account) public view returns (bool) {
    return startTime[account] != 0;
}

function balanceOf(address account) public view returns (uint256) {
    // if registered, return balance
    if (isRegistered(account)) {
        uint256 timeSinceStart = block.timestamp.sub(
            startTime[account],
            "Subtraction cannot overflow"
        );
        uint256 tokensInBalance = timeSinceStart.mul(tokenPerSecond);
        return tokensInBalance;
    }
    // if not registered, return 0
    return 0;
}

ERC 20準拠でストリーミング中の最終注記


前の例は完全にERC 20に準拠していません.それらのトークンがどのように時間をかけて蓄積されたか、またはどのような合計の供給が可能かを示していないからです.例えば、UBI tokens それは移動(または燃やす)を移動する前にアカウントでUBIとしてのアカウントトークンを考慮しないでください.
この特定の例では、同様の戦略に従う解決策は複雑ではありませんが、2番目のポストを含みます.
この例の完全な作業コードはここにあります.https://github.com/nikoferro/drip-token