Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eth: Compare on chain bytecode with local copy #1203

Merged
merged 2 commits into from
Sep 10, 2021

Conversation

martonp
Copy link
Collaborator

@martonp martonp commented Sep 9, 2021

Add a shell script that generates go code containing the runtime
bytecode of the ETHSwap contract. Add a function to rpcclient to
retrieve the on chain bytecode, and add a test that compares them.

Closes #1198

Add a shell script that generates go code containing the runtime
bytecode of the ETHSwap contract. Add a function to rpcclient to
retrieve the on chain bytecode, and add a test that compares them.
Copy link
Member

@JoeGruffins JoeGruffins left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty perfect. Quick work of it.

Is it possible to have the github cli download the correct version of solc, run genruntime.sh and compare those files, so we would know if something changed in the hex bin? Maybe also a good idea for contract.go in that case, although that also requires a certain version of abigen I believe. Can be a different pr if others think it's a good idea.

Copy link
Member

@chappjc chappjc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though we're not going to be using ethClient.getCodeAt on the first iteration, it's a good method to have.

How do you guys control solc versions? I have 0.8.7 and this was a pain for me. Maybe we can allow different patch versions, at least until we are ready to lock it down?

client/asset/eth/rpcclient_harness_test.go Outdated Show resolved Hide resolved
dex/networks/eth/contracts/genruntime.sh Outdated Show resolved Hide resolved

package eth

const ETHSwapRuntimeBin = "60806040526004361061004a5760003560e01c80637249fbb61461004f57806376467cbd14610071578063ae052147146100a7578063b31597ad146100ba578063eb84e7f2146100da575b600080fd5b34801561005b57600080fd5b5061006f61006a36600461057d565b61015c565b005b34801561007d57600080fd5b5061009161008c36600461057d565b61025e565b60405161009e9190610673565b60405180910390f35b61006f6100b53660046105d1565b610349565b3480156100c657600080fd5b5061006f6100d53660046105af565b61040e565b3480156100e657600080fd5b506101486100f536600461057d565b6000602081905290815260409020805460018201546002830154600384015460048501546005860154600687015460079097015495969495939492936001600160a01b0392831693919092169160ff1688565b60405161009e9897969594939291906106e3565b32331461016857600080fd5b80600160008281526020819052604090206007015460ff16600381111561019157610191610738565b1461019b57600080fd5b6000818152602081905260409020600401546001600160a01b031633146101c157600080fd5b600081815260208190526040902060010154428111156101e057600080fd5b60008381526020819052604080822060078101805460ff191660031790556006015490513391908381818185875af1925050503d806000811461023f576040519150601f19603f3d011682016040523d82523d6000602084013e610244565b606091505b509091505060018115151461025857600080fd5b50505050565b6102a36040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081018290529060e082015290565b6000828152602081815260409182902082516101008101845281548152600182015492810192909252600281015492820192909252600380830154606083015260048301546001600160a01b03908116608084015260058401541660a0830152600683015460c0830152600783015491929160e084019160ff9091169081111561032f5761032f610738565b600381111561034057610340610738565b90525092915050565b826000341161035757600080fd5b6000811161036457600080fd5b32331461037057600080fd5b826000808281526020819052604090206007015460ff16600381111561039857610398610738565b146103a257600080fd5b6000848152602081905260409020438155600180820187905560028201869055600482018054336001600160a01b0319918216179091556005830180549091166001600160a01b0387161790553460068301556007909101805460ff1916828002179055505050505050565b32331461041a57600080fd5b8082600160008381526020819052604090206007015460ff16600381111561044457610444610738565b1461044e57600080fd5b6000828152602081905260409020600501546001600160a01b0316331461047457600080fd5b8160028260405160200161048a91815260200190565b60408051601f19818403018152908290526104a491610638565b602060405180830381855afa1580156104c1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906104e49190610596565b146104ee57600080fd5b60008381526020819052604080822060078101805460ff191660021790556006015490513391908381818185875af1925050503d806000811461054d576040519150601f19603f3d011682016040523d82523d6000602084013e610552565b606091505b509091505060018115151461056657600080fd5b505050600090815260208190526040902060030155565b60006020828403121561058f57600080fd5b5035919050565b6000602082840312156105a857600080fd5b5051919050565b600080604083850312156105c257600080fd5b50508035926020909101359150565b6000806000606084860312156105e657600080fd5b833592506020840135915060408401356001600160a01b038116811461060b57600080fd5b809150509250925092565b6004811061063457634e487b7160e01b600052602160045260246000fd5b9052565b6000825160005b81811015610659576020818601810151858301520161063f565b81811115610668576000828501525b509190910192915050565b60006101008201905082518252602083015160208301526040830151604083015260608301516060830152608083015160018060a01b0380821660808501528060a08601511660a0850152505060c083015160c083015260e08301516106dc60e0840182610616565b5092915050565b8881526020810188905260408101879052606081018690526001600160a01b038581166080830152841660a082015260c08101839052610100810161072b60e0830184610616565b9998505050505050505050565b634e487b7160e01b600052602160045260246000fdfea2646970667358221220f5008532d651b31b24a7d133ff5dd0c4461e5f6339f32c9d551cb9cf81107e6b64736f6c63430008060033"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can leave this, but it's really a job for //go:embed.

e.g.

import _ "embed"

//go:embed contracts/ETHSwap.bin.dat
var ETHSwapRuntimeBin []byte

In the above I'm loading a []byte instead of string because I converted the output of solc into an actual binary, so you don't have to do DecodeString, but it can load the hex text too. But even with a hex string, we won't actually need to generate this file.

To make an binary file, not hexadecimal text I did solc --bin-runtime --optimize ETHSwapV0.sol | xxd -r -p > ETHSwap.bin.dat, but maybe solc can be coaxed into writing a bin file.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is definitely nicer, but the only reason I prefer the current technique is that it's consistent with what the abigen does (this is what generates contract.go). There's a really long string in there as well.

Copy link
Member

@chappjc chappjc Sep 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fine. Either we check in a ~2kb binary file to use go:embed, or we put the string right in the .go file with a shell script. No biggie to me either way.
The contract bindings are actual code though, not just variables, so I see that a little differently. It's fine this way, just a little unfortunate that it's a string when we really want bytes (any conceivable use for this would have to hex.DecodeString).

exit 1
fi

solc --bin-runtime --optimize ${SOLIDITY_FILE} -o .
Copy link
Member

@chappjc chappjc Sep 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear to me what switches to use here. These are the output options I see:

  --asm                EVM assembly of the contracts.
  --asm-json           EVM assembly of the contracts in JSON format.
  --opcodes            Opcodes of the contracts.
  --bin                Binary of the contracts in hex.
  --bin-runtime        Binary of the runtime part of the contracts in hex.
  --abi                ABI specification of the contracts.

The output of --bin is larger than --bin-runtime. Which one is better to compare? I mean CodeAt worked with bin-runtime obviously, but what's the difference between these two?

Also I'm wondering if the use of optimize (and specific compiler version) are going to make this extremely fragile.

Asking for no changes here... just a conversation.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--bin returns the creation bytecode. This is what has to be sent in a transaction when you initialize a new smart contract. --bin-runtime returns the runtime bytecode, which is the code that ends up being stored on chain. This includes everything in the creation bytecode, except the constructor function and constructor arguments, as they will not need to be used again after initialization.

Why do you say that using a specific compiler version would make this fragile? I would think that not having a specific version would make it fragile. Optimize just applies some simplification rules to the unoptimized bytecode. This is a deterministic operation. If the same compiler version is used to optimize both what is deployed and what is used to compare, then we will get the same results.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you say that using a specific compiler version would make this fragile?

Ah I was thinking about optimize and how there are different levels, but you are right, the same considerations apply there as with compiler version. I was just referring to how identical contracts compiled with newer solc versions probably would get rejected, but I guess that's the point.

@martonp
Copy link
Collaborator Author

martonp commented Sep 10, 2021

I haven't really thought much about managing the solidity version. I think the whole point of locking down the version was in order to be able to do these comparisons. It definitely was a pain to work with for me as well, since 0.8.6 is no longer the most recent version. Maybe a script that downloads the correct abigen and solc versions would be nice? This could be used in the github workflow that @JoeGruffins was talking about too. I think it's a good idea to do that too, since they might patch the released version which causes a diff.

@JoeGruffins
Copy link
Member

How do you guys control solc versions?

@chappjc I know you use arch, sudo downgrade solidity (after installing solidty and downgrade) and put on the ignore packages list

@chappjc
Copy link
Member

chappjc commented Sep 13, 2021

I was thinking a less system-wide approach, but that's probably fine for my purposes. Thanks

@JoeGruffins
Copy link
Member

JoeGruffins commented Sep 15, 2021

K.I.S.S.

But it can maybe be made better if one to were make the golang-cli script ,which would also download the correct solc to a temp location I suppose, and we could just use that to regenerate.

@martonp martonp deleted the compareBytecode branch December 20, 2022 22:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

eth: Compare bytecode or swap contract with a contract on chain
3 participants