Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
ltfschoen committed Jan 7, 2025
1 parent e5091c1 commit 79d1c6a
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 57 deletions.
3 changes: 2 additions & 1 deletion _SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ Continue with [Run Services](#run-services).

* Run the following to start the Secret Development Node docker container, the Ethereum Development Node systemd service, and the Relayer systemd service.
```bash
export PROJECT_ROOT="/root/nunya"
export PROJECT_ROOT="/root/nunya" # or ~/nunya
export USE_NETWORK="localhost" # alternatively "testnet" or "mainnet"
cd $PROJECT_ROOT
$PROJECT_ROOT/scripts/run.sh | tee $PROJECT_ROOT/run.log
Expand Down Expand Up @@ -440,6 +440,7 @@ Further changes:

* Build
```bash
cd $PROJECT_ROOT/packages/pop/NunyaBusiness
pop build

* Deploy
Expand Down
4 changes: 2 additions & 2 deletions deployed.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@
"gatewayContractAddress": "secret1mfk7n6mc2cg6lznujmeckdh4x0a5ezf6hx6y8q",
"gatewayContractCodeHash": "be3db4b4c42d33300eee7801769a4176ed3046f23c08812fc2a85bc76075e1d5",
"gatewayContractAdminAddress": "secret1glfedwlusunwly7q05umghzwl6nf2vj6wr38fg",
"gatewayContractPublicKey": "0x047c4f7a52a10c051639ec0edd3e2d44fef02d993de6b8412273a78ca67f9c10c66069161d67278de0c74c501de435335163d6b7c5a22abae70e49d83a2b3debbd",
"gatewayContractEncryptionKeyForChaChaPoly1305": "A3xPelKhDAUWOewO3T4tRP7wLZk95rhBInOnjKZ/nBDG"
"gatewayContractPublicKey": "0x04b3078a5c4d56f7190b9cd03f0e359725588d2d2eb68e0db91998b76dd93f5e6fef2233f78020b2c8b464a1eeff1f565cc4983ff8f0b6e425ca793454b3aaba33",
"gatewayContractEncryptionKeyForChaChaPoly1305": "A7MHilxNVvcZC5zQPw41lyVYjS0uto4NuRmYt23ZP15v"
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion packages/hardhat/contracts/Gateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -456,10 +456,13 @@ contract Gateway is Ownable, Utils, Base64 {
// persisting the task
tasks[_taskId] = Task(bytes31(_payloadHash), false);

string memory sourceNetwork = getChainId(chain_id_1, chain_id_2, chain_id_3, chain_id_length);
console.log("------ Gateway.send - sourceNetwork: ", sourceNetwork);

//emit the task to be picked up by the relayer
emit logNewTask(
_taskId,
getChainId(chain_id_1, chain_id_2, chain_id_3, chain_id_length),
sourceNetwork,
_userAddress,
_routingInfo,
_payloadHash,
Expand Down
102 changes: 53 additions & 49 deletions packages/hardhat/contracts/JSONParser.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,69 +11,73 @@
pragma solidity ^0.8.26;

contract JSONParser {
// Custom error to save gas
error InvalidJSONFormat();
// Custom error for invalid data format
error InvalidDataFormat();

function extractKeyArray(bytes calldata data) public pure returns (uint8[] memory) {
// Skip the base64 decoding as the data is already decoded in this case
function extractKeyArray(bytes calldata data) public pure returns (uint256) {
// Skip the callback selector (4 bytes) and taskId (32 bytes)
// The actual JSON data starts after the ABI encoding overhead

// Find the "_key" property - we know it comes after "_request_id"
// Search for "[" after "_key":" pattern
// Find the position of "_key":[
bytes memory searchKey = '"_key":[';
uint256 startPos;
uint256 endPos;
bool found = false;

for (uint i = 0; i < data.length - 6; i++) {
// Look for "_key":" pattern
if (data[i] == '_' &&
data[i+1] == 'k' &&
data[i+2] == 'e' &&
data[i+3] == 'y' &&
data[i+4] == '"' &&
data[i+5] == ':') {

// Find the opening bracket
while (i < data.length && data[i] != '[') {
i++;
}
startPos = i + 1;

// Find the closing bracket
while (i < data.length && data[i] != ']') {
i++;
// Search for the key in chunks to save gas
for (uint i = 0; i < data.length - searchKey.length; i += 32) {
// Load 32 bytes at a time
bytes32 chunk;
assembly {
chunk := calldataload(add(data.offset, i))
}

// Check if our search key starts in this chunk
bool matchFound = true;
for (uint j = 0; j < searchKey.length && i + j < data.length; j++) {
if (uint8(chunk[j]) != uint8(searchKey[j])) {
matchFound = false;
break;
}
endPos = i;
}

if (matchFound) {
startPos = i + searchKey.length;
found = true;
break;
}
}

if (startPos == 0 || endPos == 0) revert InvalidJSONFormat();

// Count the numbers (commas + 1)
uint256 count = 1;
for (uint256 i = startPos; i < endPos; i++) {
if (data[i] == ',') count++;
}
if (!found) revert InvalidDataFormat();

// Create array to store results
uint8[] memory result = new uint8[](count);
uint256 resultIndex = 0;
uint256 currentNum = 0;
// Extract the array values
uint256 result;
uint256 currentNumber = 0;
uint256 arrayIndex = 0;

// Parse numbers
for (uint256 i = startPos; i < endPos; i++) {
bytes1 char = data[i];
// Process only until we hit the closing bracket or exceed 5 numbers
for (uint i = startPos; i < data.length && arrayIndex < 5; i++) {
uint8 char = uint8(data[i]);

if (char >= '0' && char <= '9') {
currentNum = currentNum * 10 + uint8(uint8(char) - 48);
}

if (char == ',' || i == endPos - 1) {
result[resultIndex] = uint8(currentNum);
currentNum = 0;
resultIndex++;
if (char >= 48 && char <= 57) { // If character is a digit
currentNumber = currentNumber * 10 + (char - 48);
} else if (char == 44 || char == 93) { // If comma or closing bracket
// Pack the number into the result
result = (result << 8) | uint8(currentNumber);
currentNumber = 0;
arrayIndex++;

if (char == 93) break; // Exit if closing bracket
}
}

return result;
}
}

function unpackArray(uint256 packed) public pure returns (uint8[5] memory) {
uint8[5] memory result;
for (uint i = 0; i < 5; i++) {
result[4-i] = uint8((packed >> (i * 8)) & 0xFF);
}
return result;
}
}
17 changes: 14 additions & 3 deletions packages/hardhat/contracts/NunyaBusiness.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import "./Utils.sol";

import "./Ownable.sol";

import "@openzeppelin/contracts/utils/Strings.sol";

/**
* @notice Gateway Receiver
* @author
Expand Down Expand Up @@ -47,7 +49,7 @@ contract NunyaBusiness is Ownable, Utils {

IGateway secretContract;

uint256 public secretContractPubkey;
uint8[] public secretContractPubkey;

mapping (uint256 => FunctionCallType) expectedResult;

Expand Down Expand Up @@ -212,8 +214,17 @@ contract NunyaBusiness is Ownable, Utils {
// To prevent it from out of gas errors then try sending it as the first key and converting the value into a fixed-length hash using Keccak256
// so it is easy to find the start and end of the `result` by index.

// JSONParser parser = new JSONParser();
// secretContractPubkey = parser.extractKeyArray(data);

// Note: If I change `value: parseUnits("10000000", "ether").toString(),` to instead be
// `value: parseUnits("10000000", "ether").toString(),` in 01_deploy_your_contracts.ts and use the below
// to parse using JSONParser, it says it needs gas of 10000000010500000000000000 but the sender's balance is:
// only 10000000000000000000000. Definately can't parse JSON.
JSONParser parser = new JSONParser();
uint256 secretContractPubkeyPackedArray = parser.extractKeyArray(data);
string memory secretContractPubkeyStr = Strings.toString(secretContractPubkeyPackedArray);
uint8[5] memory secretContractPubkey = parser.unpackArray(secretContractPubkeyPackedArray);
console.log("------ NunyaBusiness - fulfilledSecretContractPubkeyCallback - secretContractPubkey: ", secretContractPubkeyStr);

// // https://github.com/NomicFoundation/hardhat/issues/2043
// for (uint i=0; i<secretContractPubkey.length; i++) {
// console.log("------ NunyaBusiness - fulfilledSecretContractPubkeyCallback - secretContractPubkey: ", i);
Expand Down
2 changes: 1 addition & 1 deletion packages/hardhat/deploy/01_deploy_your_contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const deployYourContract: DeployFunction = async function (hre: HardhatRuntimeEn
args: [],
log: true,
gasLimit: 3000000,
value: parseUnits("0.0005", "ether").toString(), // to fund the gateway in the constructor, use when setGatewayAddress is called
value: parseUnits("10000000", "ether").toString(), // to fund the gateway in the constructor, use when setGatewayAddress is called
// autoMine: can be passed to the deploy function to make the deployment process faster on local networks by
// automatically mining the contract deployment transaction. There is no effect on live networks.
autoMine: true,
Expand Down

0 comments on commit 79d1c6a

Please sign in to comment.