Don't: Do not call onBoard on a value that has not previously had offBoard called on it
contract BadContract { ctUint64 public sum;//...functionaddWithoutCarefulOnboard() public { gtUint64 a = MpcCore.setPublic64(1); gtUint64 sum_ = MpcCore.onBoard(sum); // THIS WILL REVERT sum_ = MpcCore.add(sum_, a); sum = MpcCore.offBoard(sum_); }//...}
Do: Initialize the value by calling offBoard inside the constructor
contract GoodContract { ctUint64 public sum;constructor() {// By initializing sum with an encrypted value, we ensure// calling onBoard on sum does not revert gtUint64 sum_ = MpcCore.setPublic64(0); sum = MpcCore.offBoard(sum_); }//...functionadd() public { gtUint64 a = MpcCore.setPublic64(1); gtUint64 sum_ = MpcCore.onBoard(sum); sum_ = MpcCore.add(sum_, a); sum = MpcCore.offBoard(sum_); }//...}
Or:Check if the value is zero before calling onBoard
contract GoodContract { ctUint64 public sum;//...functionaddWithCarefulOnboard() public { gtUint64 a = MpcCore.setPublic64(1); gtUint64 sum_;// By checking if sum is equal to zero, we can verify whether// or not it is safe to call onBoard on sumif (ctUint64.unwrap(sum) ==0) { sum_ = MpcCore.setPublic64(0); } else { sum_ = MpcCore.onBoard(sum); } sum_ = MpcCore.add(sum_, a); sum = MpcCore.offBoard(sum_); }//...}