@@ -58,7 +58,7 @@ contract Gateway is Ownable, Utils, Base64 {
58
58
59
59
bytes public owner_public_key;
60
60
61
- bytes28 public gatewayAddressBase64 = encodeAddressToBase64 (address (this ));
61
+ bytes28 public nunyaAddressBase64 = encodeAddressToBase64 (address (owner ));
62
62
63
63
/*//////////////////////////////////////////////////////////////
64
64
Structs
@@ -111,7 +111,9 @@ contract Gateway is Ownable, Utils, Base64 {
111
111
Helpers
112
112
//////////////////////////////////////////////////////////////*/
113
113
114
- function ethSignedPayloadHash (bytes memory payload ) public pure returns (bytes32 payloadHash ) {
114
+ // Note: Why isn't a random nonce used to generate this, similar to how that
115
+ // is done in encryptPayload.ts to generate the payloadHash there?
116
+ function ethSignedPayloadHash (bytes memory payload ) public pure returns (bytes32 payloadHash ) {
115
117
assembly {
116
118
// Take scratch memory for the data to hash
117
119
let data := mload (0x40 )
@@ -230,13 +232,17 @@ contract Gateway is Ownable, Utils, Base64 {
230
232
console.log ("------ Gateway.prepareResultBytesToCallbackData - _taskId: " , _taskId);
231
233
console.log ("------ Gateway.prepareResultBytesToCallbackData - data.length: " , data.length );
232
234
assembly {
233
- result := mload (0x40 )
234
- mstore (result, add (100 , data.length ))
235
- mstore (add (result, 32 ), callback_selector)
236
- mstore (add (result, 36 ), _taskId)
237
- mstore (add (result, 68 ), 0x40 )
238
- mstore (add (result, 100 ), data.length )
235
+ result := mload (0x40 ) // Set `result` to point to the free memory pointer
236
+ mstore (result, add (100 , data.length )) // Update the free memory pointer
237
+ mstore (add (result, 32 ), callback_selector) // Load `callback_selector` and store at `result` + 32
238
+ mstore (add (result, 36 ), _taskId) // Load `_taskId` and store at `result` + 36
239
+ mstore (add (result, 68 ), 0x40 ) // Load `0x40` (free memory pointer) and store at `result` + 68
240
+ mstore (add (result, 100 ), data.length ) // Load `data.length` and store at `result` + 100
241
+ // Directly copy data from the transaction's call data (read only)
242
+ // that was the input data sent with the call into memory
239
243
calldatacopy (add (result, 132 ), data.offset, data.length )
244
+ // Update the free memory pointer with that
245
+ // loaded from `data.length` and stored at `result` + 132 bytes
240
246
mstore (0x40 , add (add (result, 132 ), data.length ))
241
247
}
242
248
}
@@ -549,88 +555,45 @@ contract Gateway is Ownable, Utils, Base64 {
549
555
// Hex value of `owner_public_key` is: 0x038318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75
550
556
// In base64 it is A4MYU1tUEF1Keq5gwI/EX5aHGBtP38YlvRp1P6c5f+11
551
557
// bytes memory userKey = bytes.concat(owner_public_key);
552
- //
553
- // INFO [enclave_contract_engine::wasm3] debug_print: "Decryption failed: GenericErr {\n msg: \"malformed public key\",\n}"
554
- // INFO [enclave_contract_engine::wasm3] debug_print: "verify the internal verification key matches the user address"
555
- // INFO [enclave_contract_engine::wasm3] debug_print: "msg.user_key: Binary(41344d59553174554546314b6571356777492f4558356148474274503338596c7652703150366335662b3131)"
556
- // INFO [enclave_contract_engine::wasm3] debug_print: "payload.user_key: Binary(038318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75)"
557
-
558
+
558
559
// secret1glfedwlusunwly7q05umghzwl6nf2vj6wr38fg
559
560
// note: used as the 'admin' when instantiating the Secret Gateway
560
561
// hex equivalent: 0382be33224d9cd71db7bf129dc8e102b2d63670d11daa64645b1e9a399ff7fec0
561
562
bytes memory userKey = bytes .concat ("A4K+MyJNnNcdt78SncjhArLWNnDRHapkZFsemjmf9/7A " );
562
563
563
- // 04d0ce1bd101c1a2a130185e4c63d1d7091db9ab0dca3c651998d314a1550323c02649b0960b00bb1fac896aaf4056abb605e87d55ec1805a91ddb3e32c6b89c36
564
- // base64 value: BNDOG9EBwaKhMBheTGPR1wkduasNyjxlGZjTFKFVAyPAJkmwlgsAux+siWqvQFartgXofVXsGAWpHds+Msa4nDY=
565
- // bytes memory userKey = bytes.concat(encode(hex"04d0ce1bd101c1a2a130185e4c63d1d7091db9ab0dca3c651998d314a1550323c02649b0960b00bb1fac896aaf4056abb605e87d55ec1805a91ddb3e32c6b89c36"));
566
- // bytes memory userKey = bytes.concat("BNDOG9EBwaKhMBheTGPR1wkduasNyjxlGZjTFKFVAyPAJkmwlgsAux+siWqvQFartgXofVXsGAWpHds+Msa4nDY=");
567
-
568
- // 04d0ce1bd101c1a2a130185e4c63d1d7091db9ab0dca3c651998d314a1550323c02649b0960b00bb1fac896aaf4056abb605e87d55ec1805a91ddb3e32c6b89c36
569
- // bytes memory gatewayContractPubkey = hex"04d0ce1bd101c1a2a130185e4c63d1d7091db9ab0dca3c651998d314a1550323c02649b0960b00bb1fac896aaf4056abb605e87d55ec1805a91ddb3e32c6b89c36";
570
-
571
- // 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
572
- // Hex value of `owner_public_key` is: 0x038318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75
573
- // bytes memory userPubkey = hex"038318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed75";
574
-
575
- // FIXME: Probably wrong, it should be generated like this https://docs.scrt.network/secret-network-documentation/confidential-computing-layer/ethereum-evm-developer-toolkit/usecases/vrf/using-encrypted-payloads-for-vrf#signing-the-payload-with-metamask
576
- // and likely different from `userKey`
577
564
// Output of encodePayload.ts `user_pubkey`
578
565
// 0x048318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5
579
566
// base64: BIMYU1tUEF1Keq5gwI/EX5aHGBtP38YlvRp1P6c5f+11NUfxHKhpZkby86ywjjEBavrCPmMMXRH1n2H+9XsNKqU=
580
567
bytes memory userPubkey = bytes .concat ("BIMYU1tUEF1Keq5gwI/EX5aHGBtP38YlvRp1P6c5f+11NUfxHKhpZkby86ywjjEBavrCPmMMXRH1n2H+9XsNKqU= " );
581
568
582
- // Gateway contract public key
583
- // Generated from ./packages/secret-contracts-scripts/src/functions/secretpath/generateKeys.ts
584
- // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
585
- // converted to base64: QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUE=
586
-
587
- // INFO [enclave_contract_engine::wasm3] debug_print: "Decryption failed: GenericErr {\n msg: \"malformed public key\",\n}"
588
- // INFO [enclave_contract_engine::wasm3] debug_print: "verify the internal verification key matches the user address"
589
- // INFO [enclave_contract_engine::wasm3] debug_print: "msg.user_key: Binary(4141414141414141414141414141414141414141414141414141414141414141414141414141414141414141)"
590
- // INFO [enclave_contract_engine::wasm3] debug_print: "payload.user_key: Binary(000000000000000000000000000000000000000000000000000000000000000000)"
591
- // bytes memory userKey = bytes.concat("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); // malformed public key
592
-
593
569
// Note: Since contracts only have an address, but not public keys, where the
594
570
// addresses are derived from the address of the user (or other contract) that
595
571
// created them, which are in turn are derived from the public key of a normal
596
572
// user's keypair. So we will use the public key of the `owner` that created the
597
573
// Gateway contract.
598
574
//
599
- // TODO: We will use the base64 value for both the value of the `user_key` and
600
- // the `user_pubkey`, but they should be different and `user_key` suggested to
601
- // be base64 (e.g. `AAA=`)
602
- //
603
575
// Note: In this custom Gateway.sol, the NunyaBusiness contract address is provided as an argument in its
604
576
// constructor and set to be the `owner` in storage. Furthermore, we apply `onlyOwner` modifier to this
605
577
// function that restricts calls to only be allowed to come from a `msg.sender` that is the same as the `owner`.
606
578
// If it is `msg.sender` then it would allow a call to be made from anyone, even a "fake" NunyaBusiness contract
607
579
// if `onlyOwner` was removed.
608
580
// If the Gateway contract by the Secret team was used instead then we would need a way to upgrade that contract
609
581
// to allow us to set an `owner`-like value that could be used to restrict calls to functions like this.
610
- // FIXME: Error parsing into type secret_gateway::types::Payload: Invalid unicode code point.: execute contract failed
611
- // TODO: Try changing to `"user_address":"0x0000","user_key":"AAA="`
612
582
bytes memory payload_info = abi.encodePacked (
613
583
'}","routing_info":" ' ,routing_info,
614
584
'","routing_code_hash":" ' ,routing_code_hash,
615
585
// '","user_address":"',address(owner), // Invalid unicode code point.
616
- '","user_address":"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 ' ,
586
+ '","user_address":"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 ' , // What is `address(msg.sender)`?
617
587
// '","user_key":"',owner_public_key,
618
588
// https://github.com/SecretSaturn/SecretPath/blob/main/TNLS-Gateways/secret/tests/integration.ts#L340
589
+ // Note: `user_key` must be base64 value
619
590
'","user_key":" ' ,userKey,
591
+ // Note: `callback_address` must be base64 value
620
592
'","callback_address":" '
621
593
// '","user_address":"0x0000","user_key":"AAA=","callback_address":"'
622
594
);
623
-
624
- //
625
- // // Generic error: verification key mismatch
626
- // bytes memory payload_info = abi.encodePacked(
627
- // '}","routing_info":"',routing_info,
628
- // '","routing_code_hash":"',routing_code_hash,
629
- // '","user_address":"',address(msg.sender),
630
- // '","user_key":"',senderAddressBase64,
631
- // '","callback_address":"'
632
- // );
633
- // console.log("------ Gateway.requestValue - payload_info: ", payload_info);
595
+ console.log ("------ Gateway.requestValue - msg.sender: " , msg .sender );
596
+ console.log ("------ Gateway.requestValue - payload_info: " , payload_info);
634
597
635
598
// uint32 _myArg = 123;
636
599
//construct the payload that is sent into the Secret Gateway
@@ -640,63 +603,67 @@ contract Gateway is Ownable, Utils, Base64 {
640
603
'{"data":"{\ \" myArg\ \" : ' ,
641
604
uint256toBytesString (123 ),
642
605
payload_info,
643
- // callback_address should be this EVM Gateway address, the `publicClientAddress` in this example
606
+ // callback_address in this example is the EVM Gateway address (the `publicClientAddress`)
607
+ // but our callback_selector is in NunyaBusiness.sol so we need to use that instead.
644
608
// https://docs.scrt.network/secret-network-documentation/confidential-computing-layer/ethereum-evm-developer-toolkit/usecases/vrf/using-encrypted-payloads-for-vrf#defining-variables
645
- gatewayAddressBase64, //callback_address
609
+ // Note: `callback_address` must be base64 value
610
+ nunyaAddressBase64, //callback_address
646
611
// callback selector should be a hex value already converted into base64 to be used
647
612
// as callback_selector of the request_value function in the Secret contract
648
613
// FIXME: Error parsing into type secret_gateway::types::Payload: invalid base64: 259716626: execute contract failed
649
614
// '","callback_selector":"',uint256toBytesString(_callbackSelector),
615
+ // Note: `callback_address` must be base64 value
650
616
// Note: fulfilledValueCallback - 0x0f7af612 hex, D3r2Eg== base64. Example: fulfillRandomWords - 0x38ba4614 hex, OLpGFA== base64
651
617
'","callback_selector":"D3r2Eg==","callback_gas_limit": ' ,uint256toBytesString (_callbackGasLimit),
652
618
'} '
653
619
);
654
- //
655
- // // Generic error: verification key mismatch
656
- // bytes memory payload = bytes.concat(
657
- // '{"data":"{\\"myArg\\":',
658
- // uint256toBytesString(123),
659
- // payload_info,
660
- // senderAddressBase64, //callback_address
661
- // '","callback_selector":"OLpGFA==","callback_gas_limit":', // 0x38ba4614 hex value already converted into base64, callback_selector of the fullfillRandomWords function
662
- // uint256toBytesString(_callbackGasLimit),
663
- // '}'
664
- // );
665
- // console.log("------ Gateway.requestValue - payload: ", payload);
666
620
621
+ // FIXME: This should be a random nonce and generated similar to
622
+ // how it is generated in encryptPayload.ts using `window.crypto.getRandomValues(bytes(12))`
667
623
uint256 _newNonce = nonce + 1 ;
668
624
increaseNonce (_newNonce);
669
625
console.log ("------ Gateway.requestValue - _newNonce: " , _newNonce);
670
626
671
627
//generate the payload hash using the ethereum hash format for messages
672
628
bytes32 payloadHash = ethSignedPayloadHash (payload);
673
- // console.log("------ Gateway.requestValue - payloadHash: ", payloadHash);
629
+ console.log ("------ Gateway.requestValue - payloadHash: " , payloadHash);
630
+
631
+ // FIXME: Even though we have generated the payloadHash, we haven't done it using the
632
+ // `sharedKey` that would be generated using generateKeys.ts, the same way we have done that
633
+ // in encryptPayload.ts, but neither of those TypeScript files are being used to provide inputs
634
+ // to this `requestValue` function, as they are only being used in the submitReqestValue.ts
635
+ // script that calls the `send` function in the Gateway.sol directly and does the encryption
636
+ // in TypeScript before sending the transaction to call `send`.
637
+ // It may be necessary to provide the `sharedKey` and `nonce` encrypted into this `requestValue` function
638
+ // and use them to generate the payload, but then we may as well just prepare all the
639
+ // relevant information in TypeScript and send it via NunyaBusiness to `send`.
640
+
641
+ // FIXME: How to generate payloadSignature??
642
+ // We should be providing it to the smart contract and verifying it is valid here
643
+ // https://ethereum.stackexchange.com/questions/24367/is-it-possible-to-sign-a-message-in-solidity
644
+ const payloadSignature = ...
674
645
675
- bytes memory emptyBytes = hex "0000 " ;
646
+ // FIXME: Do not know how to recover public key using Solidity this way,
647
+ // only know how to do it in TypeScript.
648
+ uint256 userPubkeyRecovered = recoverPublicKey (payloadHash, payloadSignature);
676
649
677
- // TODO - make `user_key` a unique key different from `user_pubkey`
678
- // bytes memory userKey = bytes.concat(senderAddressBase64); // equals AAA= in base64
650
+ bytes memory emptyBytes = hex "0000 " ; // equals AAA= in base64
679
651
680
652
// ExecutionInfo struct
681
653
ExecutionInfo memory executionInfo = ExecutionInfo ({
682
- // user_key: gatewayContractPubkey,
683
- user_key: userKey,
684
- // user_key: userKey, // FIXME - use this instead when resolve issue
685
- // user_key: emptyBytes, // equals AAA= in base64
686
- // FIXME: use of `secret_gateway_signer_pubkey` does not compile, what alternative to use?
687
- // user_pubkey: uint256toBytesString(secret_gateway_signer_pubkey),
654
+ // Note: `user_key` and `user_pubkey` here are in bytes, NOT base64 like in the `payload`
655
+ user_key: userKey, // emptyBytes,
656
+ // user_pubkey: uint256toBytesString(userPubkeyRecovered),
688
657
// Refer to ./packages/secret-contracts/secret-gateway/src/msg.rs that shows
689
658
// what to use for `user_key` and `user_pubkey`, as they are different
690
- user_pubkey: userPubkey,
691
- // user_pubkey: userKey,
692
- // user_pubkey: emptyBytes, // Fill with 0 bytes
659
+ user_pubkey: userPubkey, // emptyBytes,
693
660
routing_code_hash: routing_code_hash, // custom contract codehash on Secret
694
661
task_destination_network: task_destination_network,
695
662
handle: "request_value " ,
696
663
nonce: bytes12 (toBytes (_newNonce)),
697
664
callback_gas_limit: _callbackGasLimit,
698
665
payload: payload,
699
- // TODO : add a payload signature
666
+ // FIXME : add a payload signature, as it `payloadHash` is incorrect
700
667
// Signature of hash of encrypted input values
701
668
// payload_signature: emptyBytes // empty signature, fill with 0 bytes
702
669
payload_signature: bytes32ToBytes (payloadHash)
@@ -770,9 +737,7 @@ contract Gateway is Ownable, Utils, Base64 {
770
737
'{"data":"{\ \" callbackSelector\ \" : ' ,
771
738
uint256toBytesString (_callbackSelector),
772
739
payload_info,
773
- // callback_address should be this EVM Gateway address, the `publicClientAddress` in this example
774
- // https://docs.scrt.network/secret-network-documentation/confidential-computing-layer/ethereum-evm-developer-toolkit/usecases/vrf/using-encrypted-payloads-for-vrf#defining-variables
775
- gatewayAddressBase64, //callback_address
740
+ nunyaAddressBase64, //callback_address
776
741
'","callback_selector":"OLpGFA==","callback_gas_limit": ' , // 0x38ba4614 hex value already converted into base64, callback_selector of the fulfillRandomWords function
777
742
uint256toBytesString (_callbackGasLimit),
778
743
'} '
0 commit comments