-
Notifications
You must be signed in to change notification settings - Fork 0
Add scripts, transactions and a test example on how to interact with Solidty contracts through Flow EVM #6
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
access(all) contract SolidityContractsRegistry { | ||
|
||
access(all) let contractRegistry: {String: [UInt8; 20]} | ||
|
||
access(all) event ContractRegistered(name: String, address: [UInt8; 20]) | ||
|
||
access(all) | ||
fun registerContract(name: String, address: [UInt8; 20]) { | ||
self.contractRegistry[name] = address | ||
emit ContractRegistered(name: name, address: address) | ||
} | ||
|
||
init() { | ||
self.contractRegistry = {} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import "SolidityContractsRegistry" | ||
|
||
access(all) | ||
fun main(contractName: String): [UInt8; 20]? { | ||
return SolidityContractsRegistry.contractRegistry[contractName] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import Test | ||
import BlockchainHelpers | ||
|
||
access(all) let serviceAccount = Test.serviceAccount() | ||
|
||
access(all) | ||
fun setup() { | ||
let err = Test.deployContract( | ||
name: "SolidityContractsRegistry", | ||
path: "../contracts/SolidityContractsRegistry.cdc", | ||
arguments: [] | ||
) | ||
Test.expect(err, Test.beNil()) | ||
} | ||
|
||
access(all) | ||
fun testCreateCOA() { | ||
let txResult = executeTransaction( | ||
"../transactions/create_coa.cdc", | ||
[750.0], | ||
serviceAccount | ||
) | ||
|
||
Test.expect(txResult, Test.beSucceeded()) | ||
} | ||
|
||
access(all) | ||
fun testDeployMultiply7Contract() { | ||
// contract Multiply7 { | ||
// event Print(uint); | ||
// function multiply(uint input) returns (uint) { | ||
// Print(input * 7); | ||
// return input * 7; | ||
// } | ||
// } | ||
// ABI for the above Solidity contract | ||
let contractCode = "6060604052341561000f57600080fd5b60eb8061001d6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063c6888fa1146044575b600080fd5b3415604e57600080fd5b606260048080359060200190919050506078565b6040518082815260200191505060405180910390f35b60007f24abdb5865df5079dcc5ac590ff6f01d5c16edbc5fab4e195d9febd1114503da600783026040518082815260200191505060405180910390a16007820290509190505600a165627a7a7230582040383f19d9f65246752244189b02f56e8d0980ed44e7a56c0b200458caad20bb0029" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a way to pull this value from a local JSON file containing Cadence JSON args? |
||
let txResult = executeTransaction( | ||
"../transactions/deploy_solidity_contract.cdc", | ||
["Multiply7", contractCode], | ||
serviceAccount | ||
) | ||
|
||
Test.expect(txResult, Test.beSucceeded()) | ||
} | ||
|
||
access(all) | ||
fun testCallMultiply7() { | ||
let scriptResult = executeScript( | ||
"../scripts/solidity_contract_address.cdc", | ||
["Multiply7"] | ||
) | ||
Test.expect(scriptResult, Test.beSucceeded()) | ||
let contractAddress = (scriptResult.returnValue as! [UInt8; 20]?)! | ||
|
||
let txResult = executeTransaction( | ||
"../transactions/solidity_contract_call.cdc", | ||
[contractAddress], | ||
serviceAccount | ||
) | ||
|
||
Test.expect(txResult, Test.beSucceeded()) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import "FungibleToken" | ||
import "FlowToken" | ||
import "EVM" | ||
|
||
transaction(amount: UFix64) { | ||
let sentVault: @FlowToken.Vault | ||
let auth: auth(Storage) &Account | ||
|
||
prepare(signer: auth(Storage) &Account) { | ||
let vaultRef = signer.storage.borrow<auth(FungibleToken.Withdraw) &FlowToken.Vault>( | ||
from: /storage/flowTokenVault | ||
) ?? panic("Could not borrow reference to the owner's Vault!") | ||
|
||
self.sentVault <- vaultRef.withdraw(amount: amount) as! @FlowToken.Vault | ||
self.auth = signer | ||
} | ||
|
||
execute { | ||
let account <- EVM.createCadenceOwnedAccount() | ||
account.deposit(from: <-self.sentVault) | ||
|
||
self.auth.storage.save<@EVM.CadenceOwnedAccount>( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we'd also want to issue an un-entitled COA Capability at |
||
<-account, | ||
to: StoragePath(identifier: "evm")! | ||
) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import "EVM" | ||
import "SolidityContractsRegistry" | ||
|
||
transaction(contractName: String, contractCode: String) { | ||
let coa: auth(EVM.Deploy) &EVM.CadenceOwnedAccount | ||
|
||
prepare(signer: auth(Storage) &Account) { | ||
self.coa = signer.storage.borrow<auth(EVM.Deploy) &EVM.CadenceOwnedAccount>( | ||
from: /storage/evm | ||
) ?? panic("Could not borrow reference to the COA!") | ||
} | ||
|
||
execute { | ||
let contractAddress = self.coa.deploy( | ||
code: contractCode.decodeHex(), | ||
gasLimit: 110000, | ||
value: EVM.Balance(attoflow: 0) | ||
) | ||
|
||
SolidityContractsRegistry.registerContract( | ||
name: contractName, | ||
address: contractAddress.bytes | ||
) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import "EVM" | ||
|
||
transaction(addressBytes: [UInt8; 20]) { | ||
let coa: auth(EVM.Call) &EVM.CadenceOwnedAccount | ||
|
||
prepare(signer: auth(Storage) &Account) { | ||
self.coa = signer.storage.borrow<auth(EVM.Call) &EVM.CadenceOwnedAccount>( | ||
from: /storage/evm | ||
) ?? panic("Could not borrow reference to the COA!") | ||
} | ||
|
||
execute { | ||
let data = EVM.encodeABIWithSignature("multiply(uint256)", [UInt256(6)]) | ||
let txResult = self.coa.call( | ||
to: EVM.EVMAddress(bytes: addressBytes), | ||
data: data, | ||
gasLimit: 35000, | ||
value: EVM.Balance(attoflow: 0) | ||
) | ||
|
||
assert( | ||
txResult.status == EVM.Status.successful, | ||
message: txResult.errorCode.toString() | ||
) | ||
|
||
let returnedValues = EVM.decodeABI(types: [Type<UInt256>()], data: txResult.data) | ||
let value = returnedValues[0] as! UInt256 | ||
assert(value == 42) // 6 * 7 = 42 | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting idea...I wonder if something like a Cadence-native diamond pattern (ERC-2535) would be a useful example