馃摉 Private Key Management of CreateX Deployer 路 pcaversaccio/createx 路 Discussion #61 (original) (raw)

For the track record, I converted this issue from @radeksvarz into this discussion thread and I also pinned it to the discussion tab.

@radeksvarz thanks for asking these important questions. I will try to address them in the most transparent way:

// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.23;

import {CreateX} from "./src/CreateX.sol";

contract CreationCodeHashCreateX { function creationCodeHashCreateX() external pure returns (bytes32) { return keccak256(type(CreateX).creationCode); } }

We have sacrificed the beauty of keyless deployment for a fallback option, particularly to be future-proof. In our opinion, this is much more scalable. I add a link to this comment in the README (see PR #62). @mds1 please add any further insights that I missed. @radeksvarz I hope I was able to address your concerns.

You must be logged in to vote

5 replies

@radeksvarz

@pcaversaccio Thanks for very open and transparent clarification.

ad Question 1: Risk of losing the private key

While researching MPC and some other co-signing options, I came to idea just to have PK setup with shamir 5/7 with distribution among key public good projects.
I propose that you make somehow backup of deployer's PK in some encrypted form and store that with e.g. ETH Foundation or some other trusted party. This should decrease the probability of the risk of losing PK.

ad Question 2: Risk of leaking the private key

Not sure that it could help now, anyway - I was planning to use Trezor / Keystone HW for signing, so PK would not leave the device. I guess you could import BIP39 seed of the PK if you have that. This can significantly decrease risk of leaking the PK.

ad front running risk and crosschecking the code - I rather check deployed runtime code:

> cast keccak $(cast code 0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed --flashbots)
0xbd8a7ea8cfca7b4e5f5041d7d4b17bc317c5ce42cfbc42066a00cf26b43eb53f

note for others: --flashbots are for mainnet, use --rpc-url RPC_URL for other chains

@pcaversaccio

While researching MPC and some other co-signing options, I came to idea just to have PK setup with shamir 5/7 with distribution among key public good projects. I propose that you make somehow backup of deployer's PK in some encrypted form and store that with e.g. ETH Foundation or some other trusted party. This should decrease the probability of the risk of losing PK.

The (based 馃槃) private key for 0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed was securely mined using profanity2 and thus an SSS algorithm doesn't work here. I know SSS or threshold signature schemes pretty well from my old Bitcoin days. These approaches don't work here, unfortunately, otherwise we would have done so. There is a zero chance that I will store our encrypted PK with any other parties, am sorry. The PK is already safely backed up (multiple times; including an air-gapped computer) over two continents and the only person I trust for this setup is @mds1. I write this here publicly so anyone is aware of this deliberate choice.

Not sure that it could help now, anyway - I was planning to use Trezor / Keystone HW for signing, so PK would not leave the device. I guess you could import BIP39 seed of the PK if you have that. This can significantly decrease risk of leaking the PK.

As mentioned above, the private key for 0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed was securely mined using profanity2 and thus no BIP39 seed is available for this case.

I can confirm that the runtime bytecode hash of CreateX is 0xbd8a7ea8cfca7b4e5f5041d7d4b17bc317c5ce42cfbc42066a00cf26b43eb53f. The reason why I prefer referring to the contract creation bytecode is that it's easier to obtain the original benchmark hash via Solidity:

// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.23;

import {CreateX} from "./src/CreateX.sol";

contract BytecodeHashesCreateX { function creationCodeHashCreateX() external pure returns (bytes32) { // This works and returns 0x12ec861579b63a3ab9db3b5a23c57d56402ad3061475b088f17054e2f2daf22f. return keccak256(type(CreateX).creationCode); }

function runtimeCodeHashCreateX() external pure returns (bytes32) {
   // This doesn't work since the type information `runtimeCode` doesn't work for contracts containing immutable variables, which `CreateX` does.
    return keccak256(type(CreateX).runtimeCode);
}

}

FWIW, I document those two hashes in the README (see PR #64).

@radeksvarz

I really welcome your transparency on this. It is crucial for users to understand the risks.

There is a zero chance that I will store our encrypted PK with any other parties, am sorry. The PK is already safely backed up (multiple times; including an air-gapped computer) over two continents and the only person I trust for this setup is @mds1. I write this here publicly so anyone is aware of this deliberate choice.

Is there any procedure in place when one (or both) of you becomes permanently unavailable for the deployment requests? (not that I wish you to).

@pcaversaccio

Is there any procedure in place when one (or both) of you becomes permanently unavailable for the deployment requests? (not that I wish you to).

There are two scenarios:

  1. Target chain supports pre-EIP-155 transactions: Use our pre-signed transactions for the deployment. No interactions from us needed.
  2. Target chain doesn't support pre-EIP-155 transactions: Open a discussion with the chain's core devs to add CreateX as a predeploy. No interactions from us needed but will be time-consuming and slow.

I would argue that 90% (at least) of the chains are covered by scenario 1). For scenario 2), the community can push for the deployment without us being part of it.

@pcaversaccio

As an interesting addendum: This morning I discovered that Geth has disabled sending (!= network layer validation, which is still possible) pre-EIP-155 transactions, thus making it even harder to use a keyless deployment approach. See my tweet here.