Sharding状況下でのatomic contract state communicationが可能なevm opcodeについて


#1

selenityに移った後のために、今の時点でshard間でstate communicationが可能なopcodeを考えてみる。

前提条件1. shardは状態を変更するcontract毎に分けられる
前提条件2. stateDBに関しては現状から変わらない
前提条件3. 2つのContractの状態を変更するtransactionの場合は、自動的に2つのtransactionに分けられてブロードキャストされる。
前提条件4. トランザクションの実行結果として変更された部分はレシートに記録される

前提条件は https://github.com/ethereum/wiki/wiki/Sharding-FAQs を参考にした。

  1. contractのstateが決定的なとき:
    つまり、いつ実行しても必ず同じstateになるもの
  2. contractのstateが非決定的なとき:
    事前に実行されたtransactionの状況により結果が変わるもの

1.の時は自明で問題はなさそう

2.の時にatomic性を担保するにはどうしたらよいか?

この辺りを参考に考えないといけなさそう。

処理能力を無視するのであれば、限りなくすべてのトランザクションを1の状態にするというアプローチもあり。つまり各contractを変更できるtransactionは1ブロックに1つにしちゃうとか。。。
storage address毎に判定するぐらいまで緩和してもよさそう。これだと結構な量のtransactionを1ブロックに入れられる。

keyとしては Hash(Hash(contract address).concat(Hash(storage address)))

この辺りまでの話はレシートに乗せる情報か。


#2

すごい初歩的な質問なのですが、上記って具体的にはどういう場合ですか?


#3

1番簡単なユースケースとしてはDEXですね。同じオーダーに2つのオファーがあった場合等です。


#4

レイヤーがばらばらになるけど忘れないうちにメモ。
現状のopcodeとして、分割ポイントとなるのはopcall, opstatickcall, opdellegatecall

solidityのレイヤーで考えると、他のContractを呼び出す部分がトランザクションとしての分割ポイントになる。
なのでここはPromise的な記述になるはず。
コンパイラー任せにしてもいいけど、コーダー側で指定させる方がいいかな。なんとなく。


#5

opcodeの話。
現状でも定義されているopcall, opdelegatecall, opstaticcallのcall系がContractの切り替え点になるので、transactionとして分離させるポイントはこれらcall系のopcodeで判別できる。
が、さらに以下の2点についても考慮する必要があると思う。

  1. その呼び出しが前処理なのか、後処理なのか。これらは前後のコードでしか判別不可。つまりプログラマに多分に判断が委ねられる部分だと思う。
  2. 他のContractを呼び出す=別のshardの実行結果を呼び出す。 なので、どのtransactionReceiptを見たらいいか?というopcodeに変わると思われる。とするなら、これらのopcodeは引数としてさらにtransaction id を持つ必要がある。