diff --git a/core/types/suave_structs.go b/core/types/suave_structs.go index ac16d1953..56fe691d3 100755 --- a/core/types/suave_structs.go +++ b/core/types/suave_structs.go @@ -1,5 +1,5 @@ // Code generated by suave/gen. DO NOT EDIT. -// Hash: 4be2661c782070850b22aff4e4fe0e5c23a870c6ae7a2822ec973ed7135fa839 +// Hash: e4f98bb3a3dbbcc1e9f0ed4f9108ee38744a6582067705ad2f4e88db19ebb4cc package types import "github.com/ethereum/go-ethereum/common" diff --git a/core/vm/contracts_suave.go b/core/vm/contracts_suave.go index 145cdf54e..5e74fb176 100644 --- a/core/vm/contracts_suave.go +++ b/core/vm/contracts_suave.go @@ -50,6 +50,15 @@ func (b *suaveRuntime) randomUint256() (*big.Int, error) { return num, nil } +func (b *suaveRuntime) randomBytes(numBytes uint64) ([]byte, error) { + buf := make([]byte, numBytes) + _, err := rand.Read(buf) + if err != nil { + return nil, err + } + return buf, nil +} + /* Confidential store precompiles */ func (b *suaveRuntime) confidentialStore(dataId types.DataId, key string, data []byte) error { diff --git a/core/vm/contracts_suave_runtime_adapter.go b/core/vm/contracts_suave_runtime_adapter.go index 566b76bc0..3c6759a4e 100644 --- a/core/vm/contracts_suave_runtime_adapter.go +++ b/core/vm/contracts_suave_runtime_adapter.go @@ -1,5 +1,5 @@ // Code generated by suave/gen. DO NOT EDIT. -// Hash: 4be2661c782070850b22aff4e4fe0e5c23a870c6ae7a2822ec973ed7135fa839 +// Hash: e4f98bb3a3dbbcc1e9f0ed4f9108ee38744a6582067705ad2f4e88db19ebb4cc package vm import ( @@ -31,6 +31,7 @@ type SuaveRuntime interface { newBuilder() (string, error) newDataRecord(decryptionCondition uint64, allowedPeekers []common.Address, allowedStores []common.Address, dataType string) (types.DataRecord, error) privateKeyGen(crypto types.CryptoSignature) (string, error) + randomBytes(numBytes uint64) ([]byte, error) randomUint256() (*big.Int, error) signEthTransaction(txn []byte, chainId string, signingKey string) ([]byte, error) signMessage(digest []byte, crypto types.CryptoSignature, signingKey string) ([]byte, error) @@ -54,6 +55,7 @@ var ( newBuilderAddr = common.HexToAddress("0x0000000000000000000000000000000053200001") newDataRecordAddr = common.HexToAddress("0x0000000000000000000000000000000042030000") privateKeyGenAddr = common.HexToAddress("0x0000000000000000000000000000000053200003") + randomBytesAddr = common.HexToAddress("0x000000000000000000000000000000007770000b") randomUint256Addr = common.HexToAddress("0x0000000000000000000000000000000077700256") signEthTransactionAddr = common.HexToAddress("0x0000000000000000000000000000000040100001") signMessageAddr = common.HexToAddress("0x0000000000000000000000000000000040100003") @@ -64,7 +66,7 @@ var ( ) var addrList = []common.Address{ - buildEthBlockAddr, confidentialInputsAddr, confidentialRetrieveAddr, confidentialStoreAddr, contextGetAddr, doHTTPRequestAddr, ethcallAddr, extractHintAddr, fetchDataRecordsAddr, fillMevShareBundleAddr, newBuilderAddr, newDataRecordAddr, privateKeyGenAddr, randomUint256Addr, signEthTransactionAddr, signMessageAddr, simulateBundleAddr, simulateTransactionAddr, submitBundleJsonRPCAddr, submitEthBlockToRelayAddr, + buildEthBlockAddr, confidentialInputsAddr, confidentialRetrieveAddr, confidentialStoreAddr, contextGetAddr, doHTTPRequestAddr, ethcallAddr, extractHintAddr, fetchDataRecordsAddr, fillMevShareBundleAddr, newBuilderAddr, newDataRecordAddr, privateKeyGenAddr, randomBytesAddr, randomUint256Addr, signEthTransactionAddr, signMessageAddr, simulateBundleAddr, simulateTransactionAddr, submitBundleJsonRPCAddr, submitEthBlockToRelayAddr, } type SuaveRuntimeAdapter struct { @@ -112,6 +114,9 @@ func (b *SuaveRuntimeAdapter) run(addr common.Address, input []byte) ([]byte, er case privateKeyGenAddr: return b.privateKeyGen(input) + case randomBytesAddr: + return b.randomBytes(input) + case randomUint256Addr: return b.randomUint256(input) @@ -647,6 +652,44 @@ func (b *SuaveRuntimeAdapter) privateKeyGen(input []byte) (res []byte, err error } +func (b *SuaveRuntimeAdapter) randomBytes(input []byte) (res []byte, err error) { + var ( + unpacked []interface{} + result []byte + ) + + _ = unpacked + _ = result + + unpacked, err = artifacts.SuaveAbi.Methods["randomBytes"].Inputs.Unpack(input) + if err != nil { + err = errFailedToUnpackInput + return + } + + var ( + numBytes uint64 + ) + + numBytes = unpacked[0].(uint64) + + var ( + value []byte + ) + + if value, err = b.impl.randomBytes(numBytes); err != nil { + return + } + + result, err = artifacts.SuaveAbi.Methods["randomBytes"].Outputs.Pack(value) + if err != nil { + err = errFailedToPackOutput + return + } + return result, nil + +} + func (b *SuaveRuntimeAdapter) randomUint256(input []byte) (res []byte, err error) { var ( unpacked []interface{} diff --git a/core/vm/contracts_suave_runtime_adapter_test.go b/core/vm/contracts_suave_runtime_adapter_test.go index f3ecb2e4b..b761916cc 100644 --- a/core/vm/contracts_suave_runtime_adapter_test.go +++ b/core/vm/contracts_suave_runtime_adapter_test.go @@ -96,6 +96,14 @@ func (m *mockRuntime) randomUint256() (*big.Int, error) { return new(big.Int).SetUint64(9001), nil } +func (m *mockRuntime) randomBytes(length uint64) ([]byte, error) { + var bytes = make([]byte, length) + for i := range bytes { + bytes[i] = 0x1 + } + return bytes, nil +} + func TestRuntimeAdapter(t *testing.T) { adapter := &SuaveRuntimeAdapter{ impl: &mockRuntime{}, diff --git a/suave/artifacts/SuaveLib.json b/suave/artifacts/SuaveLib.json index 013023e16..09b533b46 100644 --- a/suave/artifacts/SuaveLib.json +++ b/suave/artifacts/SuaveLib.json @@ -1 +1 @@ -[{"type":"error","name":"PeekerReverted","inputs":[{"name":"addr","type":"address"},{"name":"err","type":"bytes"}]},{"type":"function","name":"buildEthBlock","inputs":[{"name":"blockArgs","type":"tuple","internalType":"struct Suave.BuildBlockArgs","components":[{"name":"slot","type":"uint64","internalType":"uint64"},{"name":"proposerPubkey","type":"bytes","internalType":"bytes"},{"name":"parent","type":"bytes32","internalType":"bytes32"},{"name":"timestamp","type":"uint64","internalType":"uint64"},{"name":"feeRecipient","type":"address","internalType":"address"},{"name":"gasLimit","type":"uint64","internalType":"uint64"},{"name":"random","type":"bytes32","internalType":"bytes32"},{"name":"withdrawals","type":"tuple[]","internalType":"struct Suave.Withdrawal[]","components":[{"name":"index","type":"uint64","internalType":"uint64"},{"name":"validator","type":"uint64","internalType":"uint64"},{"name":"Address","type":"address","internalType":"address"},{"name":"amount","type":"uint64","internalType":"uint64"}]},{"name":"extra","type":"bytes","internalType":"bytes"},{"name":"beaconRoot","type":"bytes32","internalType":"bytes32"},{"name":"fillPending","type":"bool","internalType":"bool"}]},{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"namespace","type":"string","internalType":"string"}],"outputs":[{"name":"blockBid","type":"bytes","internalType":"bytes"},{"name":"executionPayload","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"confidentialInputs","outputs":[{"name":"confindentialData","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"confidentialRetrieve","inputs":[{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"key","type":"string","internalType":"string"}],"outputs":[{"name":"value","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"confidentialStore","inputs":[{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"key","type":"string","internalType":"string"},{"name":"value","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"contextGet","inputs":[{"name":"key","type":"string","internalType":"string"}],"outputs":[{"name":"value","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"doHTTPRequest","inputs":[{"name":"request","type":"tuple","internalType":"struct Suave.HttpRequest","components":[{"name":"url","type":"string","internalType":"string"},{"name":"method","type":"string","internalType":"string"},{"name":"headers","type":"string[]","internalType":"string[]"},{"name":"body","type":"bytes","internalType":"bytes"},{"name":"withFlashbotsSignature","type":"bool","internalType":"bool"}]}],"outputs":[{"name":"httpResponse","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"ethcall","inputs":[{"name":"contractAddr","type":"address","internalType":"address"},{"name":"input1","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"callOutput","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"extractHint","inputs":[{"name":"bundleData","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"hints","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"fetchDataRecords","inputs":[{"name":"cond","type":"uint64","internalType":"uint64"},{"name":"namespace","type":"string","internalType":"string"}],"outputs":[{"name":"dataRecords","type":"tuple[]","internalType":"struct Suave.DataRecord[]","components":[{"name":"id","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"salt","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"decryptionCondition","type":"uint64","internalType":"uint64"},{"name":"allowedPeekers","type":"address[]","internalType":"address[]"},{"name":"allowedStores","type":"address[]","internalType":"address[]"},{"name":"version","type":"string","internalType":"string"}]}]},{"type":"function","name":"fillMevShareBundle","inputs":[{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"}],"outputs":[{"name":"encodedBundle","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"newBuilder","outputs":[{"name":"sessionid","type":"string","internalType":"string"}]},{"type":"function","name":"newDataRecord","inputs":[{"name":"decryptionCondition","type":"uint64","internalType":"uint64"},{"name":"allowedPeekers","type":"address[]","internalType":"address[]"},{"name":"allowedStores","type":"address[]","internalType":"address[]"},{"name":"dataType","type":"string","internalType":"string"}],"outputs":[{"name":"dataRecord","type":"tuple","internalType":"struct Suave.DataRecord","components":[{"name":"id","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"salt","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"decryptionCondition","type":"uint64","internalType":"uint64"},{"name":"allowedPeekers","type":"address[]","internalType":"address[]"},{"name":"allowedStores","type":"address[]","internalType":"address[]"},{"name":"version","type":"string","internalType":"string"}]}]},{"type":"function","name":"privateKeyGen","inputs":[{"name":"crypto","type":"uint8","internalType":"struct Suave.CryptoSignature"}],"outputs":[{"name":"privateKey","type":"string","internalType":"string"}]},{"type":"function","name":"randomUint256","outputs":[{"name":"value","type":"uint256","internalType":"uint256"}]},{"type":"function","name":"signEthTransaction","inputs":[{"name":"txn","type":"bytes","internalType":"bytes"},{"name":"chainId","type":"string","internalType":"string"},{"name":"signingKey","type":"string","internalType":"string"}],"outputs":[{"name":"signedTxn","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"signMessage","inputs":[{"name":"digest","type":"bytes","internalType":"bytes"},{"name":"crypto","type":"uint8","internalType":"struct Suave.CryptoSignature"},{"name":"signingKey","type":"string","internalType":"string"}],"outputs":[{"name":"signature","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"simulateBundle","inputs":[{"name":"bundleData","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"effectiveGasPrice","type":"uint64","internalType":"uint64"}]},{"type":"function","name":"simulateTransaction","inputs":[{"name":"sessionid","type":"string","internalType":"string"},{"name":"txn","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"simulationResult","type":"tuple","internalType":"struct Suave.SimulateTransactionResult","components":[{"name":"egp","type":"uint64","internalType":"uint64"},{"name":"logs","type":"tuple[]","internalType":"struct Suave.SimulatedLog[]","components":[{"name":"data","type":"bytes","internalType":"bytes"},{"name":"addr","type":"address","internalType":"address"},{"name":"topics","type":"bytes32[]","internalType":"bytes32[]"}]},{"name":"success","type":"bool","internalType":"bool"},{"name":"error","type":"string","internalType":"string"}]}]},{"type":"function","name":"submitBundleJsonRPC","inputs":[{"name":"url","type":"string","internalType":"string"},{"name":"method","type":"string","internalType":"string"},{"name":"params","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"errorMessage","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"submitEthBlockToRelay","inputs":[{"name":"relayUrl","type":"string","internalType":"string"},{"name":"builderBid","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"blockBid","type":"bytes","internalType":"bytes"}]}] \ No newline at end of file +[{"type":"error","name":"PeekerReverted","inputs":[{"name":"addr","type":"address"},{"name":"err","type":"bytes"}]},{"type":"function","name":"buildEthBlock","inputs":[{"name":"blockArgs","type":"tuple","internalType":"struct Suave.BuildBlockArgs","components":[{"name":"slot","type":"uint64","internalType":"uint64"},{"name":"proposerPubkey","type":"bytes","internalType":"bytes"},{"name":"parent","type":"bytes32","internalType":"bytes32"},{"name":"timestamp","type":"uint64","internalType":"uint64"},{"name":"feeRecipient","type":"address","internalType":"address"},{"name":"gasLimit","type":"uint64","internalType":"uint64"},{"name":"random","type":"bytes32","internalType":"bytes32"},{"name":"withdrawals","type":"tuple[]","internalType":"struct Suave.Withdrawal[]","components":[{"name":"index","type":"uint64","internalType":"uint64"},{"name":"validator","type":"uint64","internalType":"uint64"},{"name":"Address","type":"address","internalType":"address"},{"name":"amount","type":"uint64","internalType":"uint64"}]},{"name":"extra","type":"bytes","internalType":"bytes"},{"name":"beaconRoot","type":"bytes32","internalType":"bytes32"},{"name":"fillPending","type":"bool","internalType":"bool"}]},{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"namespace","type":"string","internalType":"string"}],"outputs":[{"name":"blockBid","type":"bytes","internalType":"bytes"},{"name":"executionPayload","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"confidentialInputs","outputs":[{"name":"confindentialData","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"confidentialRetrieve","inputs":[{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"key","type":"string","internalType":"string"}],"outputs":[{"name":"value","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"confidentialStore","inputs":[{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"key","type":"string","internalType":"string"},{"name":"value","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"contextGet","inputs":[{"name":"key","type":"string","internalType":"string"}],"outputs":[{"name":"value","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"doHTTPRequest","inputs":[{"name":"request","type":"tuple","internalType":"struct Suave.HttpRequest","components":[{"name":"url","type":"string","internalType":"string"},{"name":"method","type":"string","internalType":"string"},{"name":"headers","type":"string[]","internalType":"string[]"},{"name":"body","type":"bytes","internalType":"bytes"},{"name":"withFlashbotsSignature","type":"bool","internalType":"bool"}]}],"outputs":[{"name":"httpResponse","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"ethcall","inputs":[{"name":"contractAddr","type":"address","internalType":"address"},{"name":"input1","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"callOutput","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"extractHint","inputs":[{"name":"bundleData","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"hints","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"fetchDataRecords","inputs":[{"name":"cond","type":"uint64","internalType":"uint64"},{"name":"namespace","type":"string","internalType":"string"}],"outputs":[{"name":"dataRecords","type":"tuple[]","internalType":"struct Suave.DataRecord[]","components":[{"name":"id","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"salt","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"decryptionCondition","type":"uint64","internalType":"uint64"},{"name":"allowedPeekers","type":"address[]","internalType":"address[]"},{"name":"allowedStores","type":"address[]","internalType":"address[]"},{"name":"version","type":"string","internalType":"string"}]}]},{"type":"function","name":"fillMevShareBundle","inputs":[{"name":"dataId","type":"bytes16","internalType":"struct Suave.DataId"}],"outputs":[{"name":"encodedBundle","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"newBuilder","outputs":[{"name":"sessionid","type":"string","internalType":"string"}]},{"type":"function","name":"newDataRecord","inputs":[{"name":"decryptionCondition","type":"uint64","internalType":"uint64"},{"name":"allowedPeekers","type":"address[]","internalType":"address[]"},{"name":"allowedStores","type":"address[]","internalType":"address[]"},{"name":"dataType","type":"string","internalType":"string"}],"outputs":[{"name":"dataRecord","type":"tuple","internalType":"struct Suave.DataRecord","components":[{"name":"id","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"salt","type":"bytes16","internalType":"struct Suave.DataId"},{"name":"decryptionCondition","type":"uint64","internalType":"uint64"},{"name":"allowedPeekers","type":"address[]","internalType":"address[]"},{"name":"allowedStores","type":"address[]","internalType":"address[]"},{"name":"version","type":"string","internalType":"string"}]}]},{"type":"function","name":"privateKeyGen","inputs":[{"name":"crypto","type":"uint8","internalType":"struct Suave.CryptoSignature"}],"outputs":[{"name":"privateKey","type":"string","internalType":"string"}]},{"type":"function","name":"randomBytes","inputs":[{"name":"numBytes","type":"uint64","internalType":"uint64"}],"outputs":[{"name":"value","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"randomUint256","outputs":[{"name":"value","type":"uint256","internalType":"uint256"}]},{"type":"function","name":"signEthTransaction","inputs":[{"name":"txn","type":"bytes","internalType":"bytes"},{"name":"chainId","type":"string","internalType":"string"},{"name":"signingKey","type":"string","internalType":"string"}],"outputs":[{"name":"signedTxn","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"signMessage","inputs":[{"name":"digest","type":"bytes","internalType":"bytes"},{"name":"crypto","type":"uint8","internalType":"struct Suave.CryptoSignature"},{"name":"signingKey","type":"string","internalType":"string"}],"outputs":[{"name":"signature","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"simulateBundle","inputs":[{"name":"bundleData","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"effectiveGasPrice","type":"uint64","internalType":"uint64"}]},{"type":"function","name":"simulateTransaction","inputs":[{"name":"sessionid","type":"string","internalType":"string"},{"name":"txn","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"simulationResult","type":"tuple","internalType":"struct Suave.SimulateTransactionResult","components":[{"name":"egp","type":"uint64","internalType":"uint64"},{"name":"logs","type":"tuple[]","internalType":"struct Suave.SimulatedLog[]","components":[{"name":"data","type":"bytes","internalType":"bytes"},{"name":"addr","type":"address","internalType":"address"},{"name":"topics","type":"bytes32[]","internalType":"bytes32[]"}]},{"name":"success","type":"bool","internalType":"bool"},{"name":"error","type":"string","internalType":"string"}]}]},{"type":"function","name":"submitBundleJsonRPC","inputs":[{"name":"url","type":"string","internalType":"string"},{"name":"method","type":"string","internalType":"string"},{"name":"params","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"errorMessage","type":"bytes","internalType":"bytes"}]},{"type":"function","name":"submitEthBlockToRelay","inputs":[{"name":"relayUrl","type":"string","internalType":"string"},{"name":"builderBid","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"blockBid","type":"bytes","internalType":"bytes"}]}] \ No newline at end of file diff --git a/suave/artifacts/addresses.go b/suave/artifacts/addresses.go index 1e186bdf4..6694ad55a 100644 --- a/suave/artifacts/addresses.go +++ b/suave/artifacts/addresses.go @@ -1,5 +1,5 @@ // Code generated by suave/gen. DO NOT EDIT. -// Hash: 4be2661c782070850b22aff4e4fe0e5c23a870c6ae7a2822ec973ed7135fa839 +// Hash: e4f98bb3a3dbbcc1e9f0ed4f9108ee38744a6582067705ad2f4e88db19ebb4cc package artifacts import ( @@ -21,6 +21,7 @@ var ( newBuilderAddr = common.HexToAddress("0x0000000000000000000000000000000053200001") newDataRecordAddr = common.HexToAddress("0x0000000000000000000000000000000042030000") privateKeyGenAddr = common.HexToAddress("0x0000000000000000000000000000000053200003") + randomBytesAddr = common.HexToAddress("0x000000000000000000000000000000007770000b") randomUint256Addr = common.HexToAddress("0x0000000000000000000000000000000077700256") signEthTransactionAddr = common.HexToAddress("0x0000000000000000000000000000000040100001") signMessageAddr = common.HexToAddress("0x0000000000000000000000000000000040100003") @@ -44,6 +45,7 @@ var SuaveMethods = map[string]common.Address{ "newBuilder": newBuilderAddr, "newDataRecord": newDataRecordAddr, "privateKeyGen": privateKeyGenAddr, + "randomBytes": randomBytesAddr, "randomUint256": randomUint256Addr, "signEthTransaction": signEthTransactionAddr, "signMessage": signMessageAddr, @@ -81,6 +83,8 @@ func PrecompileAddressToName(addr common.Address) string { return "newDataRecord" case privateKeyGenAddr: return "privateKeyGen" + case randomBytesAddr: + return "randomBytes" case randomUint256Addr: return "randomUint256" case signEthTransactionAddr: diff --git a/suave/gen/suave_spec.yaml b/suave/gen/suave_spec.yaml index 614c9cf3c..ca16d3808 100644 --- a/suave/gen/suave_spec.yaml +++ b/suave/gen/suave_spec.yaml @@ -376,3 +376,15 @@ functions: - name: value type: uint256 description: "Random uint256" + - name: randomBytes + address: "0x000000000000000000000000000000007770000b" + description: "Generates a number of random bytes, given by the argument numBytes." + input: + - name: numBytes + type: uint64 + description: "Number of random bytes to generate" + output: + fields: + - name: value + type: bytes + description: "Randomly-generated bytes" diff --git a/suave/sol/libraries/Suave.sol b/suave/sol/libraries/Suave.sol index c44433dcc..f2acac3ff 100644 --- a/suave/sol/libraries/Suave.sol +++ b/suave/sol/libraries/Suave.sol @@ -92,6 +92,8 @@ library Suave { address public constant PRIVATE_KEY_GEN = 0x0000000000000000000000000000000053200003; + address public constant RANDOM_BYTES = 0x000000000000000000000000000000007770000b; + address public constant RANDOM_UINT256 = 0x0000000000000000000000000000000077700256; address public constant SIGN_ETH_TRANSACTION = 0x0000000000000000000000000000000040100001; @@ -246,6 +248,15 @@ library Suave { return abi.decode(data, (string)); } + function randomBytes(uint64 numBytes) internal returns (bytes memory) { + (bool success, bytes memory data) = RANDOM_BYTES.call(abi.encode(numBytes)); + if (!success) { + revert PeekerReverted(RANDOM_BYTES, data); + } + + return abi.decode(data, (bytes)); + } + function randomUint256() internal returns (uint256) { (bool success, bytes memory data) = RANDOM_UINT256.call(abi.encode()); if (!success) {