From 0fe5587c0ee1c677567e2547208f09dba3b28a28 Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Tue, 30 Jul 2024 16:44:03 -0600 Subject: [PATCH 1/4] update EVM contract to current flow-go impl --- cadence/contracts/standards/EVM.cdc | 102 ++++++++++++------ cadence/tests/flow_evm_bridge_utils_tests.cdc | 5 +- cadence/tests/transactions/save_and_load.cdc | 14 +++ 3 files changed, 88 insertions(+), 33 deletions(-) create mode 100644 cadence/tests/transactions/save_and_load.cdc diff --git a/cadence/contracts/standards/EVM.cdc b/cadence/contracts/standards/EVM.cdc index 6c4172dc..e5a075fc 100644 --- a/cadence/contracts/standards/EVM.cdc +++ b/cadence/contracts/standards/EVM.cdc @@ -6,7 +6,7 @@ import "FlowToken" access(all) contract EVM { - // Entitlements enabling finer-graned access control on a CadenceOwnedAccount + // Entitlements enabling finer-grained access control on a CadenceOwnedAccount access(all) entitlement Validate access(all) entitlement Withdraw access(all) entitlement Call @@ -21,7 +21,7 @@ contract EVM { // height or number of the block height: UInt64, // hash of the block - hash: String, + hash: [UInt8; 32], // timestamp of the block creation timestamp: UInt64, // total Flow supply @@ -29,25 +29,25 @@ contract EVM { // all gas used in the block by transactions included totalGasUsed: UInt64, // parent block hash - parentHash: String, - // hash of all the transaction receipts - receiptRoot: String, - // all the transactions included in the block - transactionHashes: [String] + parentHash: [UInt8; 32], + // root hash of all the transaction receipts + receiptRoot: [UInt8; 32], + // root hash of all the transaction hashes + transactionHashRoot: [UInt8; 32], ) - /// Transaction executed event is emitted everytime a transaction + /// Transaction executed event is emitted every time a transaction /// is executed by the EVM (even if failed). access(all) event TransactionExecuted( // hash of the transaction - hash: String, + hash: [UInt8; 32], // index of the transaction in a block index: UInt16, // type of the transaction type: UInt8, - // RLP and hex encoded transaction payload - payload: String, + // RLP encoded transaction payload + payload: [UInt8], // code indicating a specific validation (201-300) or execution (301-400) error errorCode: UInt16, // a human-readable message about the error (if any) @@ -56,19 +56,22 @@ contract EVM { gasConsumed: UInt64, // if transaction was a deployment contains a newly deployed contract address contractAddress: String, - // RLP and hex encoded logs - logs: String, - // block height in which transaction was inclued + // RLP encoded logs + logs: [UInt8], + // block height in which transaction was included blockHeight: UInt64, - // block hash in which transaction was included - blockHash: String, /// captures the hex encoded data that is returned from /// the evm. For contract deployments /// it returns the code deployed to /// the address provided in the contractAddress field. /// in case of revert, the smart contract custom error message /// is also returned here (see EIP-140 for more details). - returnedData: String + returnedData: [UInt8], + /// captures the input and output of the calls (rlp encoded) to the extra + /// precompiled contracts (e.g. Cadence Arch) during the transaction execution. + /// This data helps to replay the transactions without the need to + /// have access to the full cadence state data. + precompiledCalls: [UInt8] ) access(all) @@ -78,26 +81,28 @@ contract EVM { /// into the EVM environment. Note that this event is not emitted /// for transfer of flow tokens between two EVM addresses. /// Similar to the FungibleToken.Deposited event - /// this event includes a depositedUUID that captures the + /// this event includes a depositedUUID that captures the /// uuid of the source vault. access(all) event FLOWTokensDeposited( - address: String, - amount: UFix64, - depositedUUID: UInt64 + address: String, + amount: UFix64, + depositedUUID: UInt64, + balanceAfterInAttoFlow: UInt ) /// FLOWTokensWithdrawn is emitted when FLOW tokens are bridged /// out of the EVM environment. Note that this event is not emitted /// for transfer of flow tokens between two EVM addresses. /// similar to the FungibleToken.Withdrawn events - /// this event includes a withdrawnUUID that captures the + /// this event includes a withdrawnUUID that captures the /// uuid of the returning vault. access(all) event FLOWTokensWithdrawn( - address: String, - amount: UFix64, - withdrawnUUID: UInt64 + address: String, + amount: UFix64, + withdrawnUUID: UInt64, + balanceAfterInAttoFlow: UInt ) /// BridgeAccessorUpdated is emitted when the BridgeAccessor Capability @@ -172,9 +177,10 @@ contract EVM { to: self.bytes ) emit FLOWTokensDeposited( - address: self.toString(), - amount: amount, - depositedUUID: depositedUUID + address: self.toString(), + amount: amount, + depositedUUID: depositedUUID, + balanceAfterInAttoFlow: self.balance().attoflow ) } @@ -201,7 +207,7 @@ contract EVM { } // Strip the 0x prefix if it exists var withoutPrefix = (asHex[1] == "x" ? asHex.slice(from: 2, upTo: asHex.length) : asHex).toLower() - let bytes = withoutPrefix.decodeHex().toConstantSized<[UInt8;20]>()! + let bytes = withoutPrefix.decodeHex().toConstantSized<[UInt8; 20]>()! return EVMAddress(bytes: bytes) } @@ -405,7 +411,8 @@ contract EVM { emit FLOWTokensWithdrawn( address: self.address().toString(), amount: balance.inFLOW(), - withdrawnUUID: vault.uuid + withdrawnUUID: vault.uuid, + balanceAfterInAttoFlow: self.balance().attoflow ) return <-vault } @@ -806,4 +813,37 @@ contract EVM { ?.borrowBridgeAccessor() ?? panic("Could not borrow reference to the EVM bridge") } -} \ No newline at end of file + + /// The Heartbeat resource controls the block production. + /// It is stored in the storage and used in the Flow protocol to call the heartbeat function once per block. + access(all) + resource Heartbeat { + /// heartbeat calls commit block proposals and forms new blocks including all the + /// recently executed transactions. + /// The Flow protocol makes sure to call this function once per block as a system call. + access(all) + fun heartbeat() { + InternalEVM.commitBlockProposal() + } + } + + /// setupHeartbeat creates a heartbeat resource and saves it to storage. + /// The function is called once during the contract initialization. + /// + /// The heartbeat resource is used to control the block production, + /// and used in the Flow protocol to call the heartbeat function once per block. + /// + /// The function can be called by anyone, but only once: + /// the function will fail if the resource already exists. + /// + /// The resulting resource is stored in the account storage, + /// and is only accessible by the account, not the caller of the function. + access(all) + fun setupHeartbeat() { + self.account.storage.save(<-create Heartbeat(), to: /storage/EVMHeartbeat) + } + + init() { + self.setupHeartbeat() + } +} diff --git a/cadence/tests/flow_evm_bridge_utils_tests.cdc b/cadence/tests/flow_evm_bridge_utils_tests.cdc index 71713069..3d204c4a 100644 --- a/cadence/tests/flow_evm_bridge_utils_tests.cdc +++ b/cadence/tests/flow_evm_bridge_utils_tests.cdc @@ -85,11 +85,12 @@ fun setup() { Test.expect(err, Test.beNil()) let deploymentResult = executeTransaction( "../transactions/evm/deploy.cdc", - [getCompiledFactoryBytecode(), 15_000_000, 0.0], + [getCompiledFactoryBytecode(), UInt64(15_000_000), 0.0], bridgeAccount ) + Test.expect(deploymentResult, Test.beSucceeded()) let evts = Test.eventsOfType(Type()) - Test.assertEqual(2, evts.length) + Test.assertEqual(3, evts.length) let factoryAddressHex = getEVMAddressHexFromEvents(evts, idx: 0) err = Test.deployContract( name: "FlowEVMBridgeUtils", diff --git a/cadence/tests/transactions/save_and_load.cdc b/cadence/tests/transactions/save_and_load.cdc new file mode 100644 index 00000000..65ccdccc --- /dev/null +++ b/cadence/tests/transactions/save_and_load.cdc @@ -0,0 +1,14 @@ +import "FlowToken" + +transaction { + prepare(signer: auth(Storage) &Account) { + let v <- FlowToken.createEmptyVault(vaultType: Type<@FlowToken.Vault>()) + + signer.storage.save(<-v, to: /storage/temp) + + let loaded <- signer.storage.load<@AnyResource>(from: /storage/temp) + ?? panic("no resource found in vault storage path") + + destroy loaded + } +} \ No newline at end of file From b3203cb7767be184a9035e678c2cb79e0ff306f2 Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Tue, 30 Jul 2024 16:44:42 -0600 Subject: [PATCH 2/4] update previewnet address in flow.json --- flow.json | 56 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/flow.json b/flow.json index 8c76d43c..ba45258e 100644 --- a/flow.json +++ b/flow.json @@ -5,7 +5,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -24,7 +24,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -34,7 +34,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -72,7 +72,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -82,7 +82,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -92,7 +92,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -102,7 +102,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -112,7 +112,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -122,7 +122,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -132,7 +132,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -142,7 +142,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -152,7 +152,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -205,7 +205,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -215,7 +215,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -225,7 +225,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -235,7 +235,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -245,7 +245,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -255,7 +255,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -287,7 +287,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -297,7 +297,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -307,7 +307,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -317,7 +317,7 @@ "aliases": { "crescendo": "dfc20aee650fcbdf", "emulator": "179b6b1cb6755e31", - "previewnet": "715c57f7a59bc39b", + "previewnet": "7792cfb75d8dfdd8", "testing": "0000000000000007", "testnet": "dfc20aee650fcbdf" } @@ -353,6 +353,16 @@ "index": 2 } }, + "previewnet-service-account": { + "address": "b6763b4399a888c8", + "key": { + "type": "file", + "signatureAlgorithm": "ECDSA_secp256k1", + "hashAlgorithm": "SHA2_256", + "location": "./previewnet-service-account.pkey", + "index": 0 + } + }, "emulator-account": { "address": "f8d6e0586b0a20c7", "key": "fe809cc837ddcd7e761a482721c050aae43657448db859f4eb8fc421e9609938" @@ -362,7 +372,7 @@ "key": "c1e4c9d9dca9e4d5e9b0b5a9a8e8b9c5d6f4a8b9c5d6f4a8b9c5d6f4a8b9c5d6" }, "previewnet-flow-evm-bridge": { - "address": "715c57f7a59bc39b", + "address": "7792cfb75d8dfdd8", "key": { "type": "google-kms", "hashAlgorithm": "SHA2_256", From 9ae06ef571b4fd21d30590eaa3f6dbbdcf9a404c Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Tue, 30 Jul 2024 16:47:37 -0600 Subject: [PATCH 3/4] updated Flow & EVM bridge deployments in README --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 98fb3b11..bbafb90b 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,11 @@ addresses: |Contracts|PreviewNet|Testnet|Mainnet| |---|---|---|---| -|All Cadence Bridge contracts|`0x715c57f7a59bc39b`|`0xdfc20aee650fcbdf`|TBD| -|[`FlowEVMBridgeFactory.sol`](./solidity/src/FlowBridgeFactory.sol)|`0xf23c8619603434f7f71659820193c8e491feb1d9`|TBD|TBD| -|[`FlowEVMBridgeDeploymentRegistry.sol`](./solidity/src/FlowEVMBridgeDeploymentRegistry.sol)|`0x544ef4ed9209ebe6989bed9e543632512afb25de`|TBD|TBD| -|[`FlowEVMBridgedERC20Deployer.sol`](./solidity/src/FlowEVMBridgedERC20Deployer.sol)|`0xc5577d2935ef0556b37358d8b92aa578f1e7564e`|TBD|TBD| -|[`FlowEVMBridgedERC721Deployer.sol`](./solidity/src/FlowEVMBridgedERC721Deployer.sol)|`0xd5bf043e8d5e6e007ebfdefebef7f4c96de5d40a`|TBD|TBD| +|All Cadence Bridge contracts|`0x7792cfb75d8dfdd8`|`0xdfc20aee650fcbdf`|TBD| +|[`FlowEVMBridgeFactory.sol`](./solidity/src/FlowBridgeFactory.sol)|`0xb0885c08995a053d8dcadce1c66b2fb11e40b868`|TBD|TBD| +|[`FlowEVMBridgeDeploymentRegistry.sol`](./solidity/src/FlowEVMBridgeDeploymentRegistry.sol)|`0xfadbc0c156f6679d1ac9eb271d4e55dce7de8802`|TBD|TBD| +|[`FlowEVMBridgedERC20Deployer.sol`](./solidity/src/FlowEVMBridgedERC20Deployer.sol)|`0x9d5fe779e35d1f13abd875dd6c2b49f20e813054`|TBD|TBD| +|[`FlowEVMBridgedERC721Deployer.sol`](./solidity/src/FlowEVMBridgedERC721Deployer.sol)|`0x211f54ca1e325a3946ed67aeefcc6cc32b1e833d`|TBD|TBD| ## Interacting with the bridge From be5f7fde15f5bd21cc04764db5c016720adb93af Mon Sep 17 00:00:00 2001 From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com> Date: Tue, 30 Jul 2024 16:51:35 -0600 Subject: [PATCH 4/4] remove unused transaction --- cadence/tests/transactions/save_and_load.cdc | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 cadence/tests/transactions/save_and_load.cdc diff --git a/cadence/tests/transactions/save_and_load.cdc b/cadence/tests/transactions/save_and_load.cdc deleted file mode 100644 index 65ccdccc..00000000 --- a/cadence/tests/transactions/save_and_load.cdc +++ /dev/null @@ -1,14 +0,0 @@ -import "FlowToken" - -transaction { - prepare(signer: auth(Storage) &Account) { - let v <- FlowToken.createEmptyVault(vaultType: Type<@FlowToken.Vault>()) - - signer.storage.save(<-v, to: /storage/temp) - - let loaded <- signer.storage.load<@AnyResource>(from: /storage/temp) - ?? panic("no resource found in vault storage path") - - destroy loaded - } -} \ No newline at end of file