Compare commits
No commits in common. "c39a3cd90bd438cdaece891844bd3c23867e8ccf" and "0a2c9680fca84a70ef27c374d671fac776a5753b" have entirely different histories.
c39a3cd90b
...
0a2c9680fc
39
README.md
39
README.md
|
@ -11,9 +11,9 @@ The goal is to use this as an alternative for ssl to web3 to verify its the corr
|
||||||
- [x] Keep it as simple as posible.
|
- [x] Keep it as simple as posible.
|
||||||
|
|
||||||
## ToDo and wanted features:
|
## ToDo and wanted features:
|
||||||
- [ ] Integrate CIDStorage library to the Dapp Indexer smart contract
|
|
||||||
- [ ] Create an event for metadata information about the CID.
|
- [ ] Create an event for metadata information about the CID.
|
||||||
- [ ] Support of the [CID Specification](https://github.com/multiformats/cid?tab=readme-ov-file)
|
- [ ] Support other type of hashes or structure storage
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
@ -41,44 +41,11 @@ $ forge snapshot
|
||||||
$ anvil
|
$ anvil
|
||||||
```
|
```
|
||||||
|
|
||||||
### Enviorment Variables
|
|
||||||
|
|
||||||
|
|
||||||
### Deploy
|
### Deploy
|
||||||
|
|
||||||
#### Option1: Deployment script (recommended)
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ ./deploy.sh
|
$ forge script script/Counter.s.sol:CounterScript --rpc-url <your_rpc_url> --private-key <your_private_key>
|
||||||
```
|
```
|
||||||
> IMPORTANT: verify .env information before executing the deployment script
|
|
||||||
|
|
||||||
**verify by attaching the deployed contract test:**
|
|
||||||
|
|
||||||
Once you deployed the contract with the previous script execution you can test
|
|
||||||
the correct smartcontract operations by running the `DeployedDappIndexer.s.sol`
|
|
||||||
script
|
|
||||||
|
|
||||||
should set after deploying the smart contract in the .env named after
|
|
||||||
DAPPINDEXERADDRS, once you update the address you can run the following
|
|
||||||
script to verify it was deployed correctly.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$source .env
|
|
||||||
$forge script script/DeployedDappIndexer.s.sol:DappIndexerScript --fork-url $PROVIDER_URL --private-key $PK0 --broadcast
|
|
||||||
```
|
|
||||||
#### Option2: Script deployment and test
|
|
||||||
using the script follows diferent verifications first before deploying the
|
|
||||||
contract, more about it here.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$source .env
|
|
||||||
$forge script script/DappIndexer.s.sol:DappIndexerScript --fork-url $PROVIDER_URL --private-key $PK0 --broadcast
|
|
||||||
```
|
|
||||||
> where:
|
|
||||||
> PROVIDER_URL can be either the anvil fork or a blockchain RPC
|
|
||||||
> $PK0
|
|
||||||
|
|
||||||
|
|
||||||
### Cast
|
### Cast
|
||||||
|
|
||||||
|
|
11
deploy.sh
11
deploy.sh
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
. ./.env
|
|
||||||
forge create --rpc-url $PROVIDER_URL \
|
|
||||||
--constructor-args $ACC0 $ACC0 \
|
|
||||||
--private-key $PK0 \
|
|
||||||
src/DappIndexer.sol:DappIndexer
|
|
||||||
|
|
||||||
#forge create --rpc-url $PROVIDER_URL \
|
|
||||||
# --constructor-args $ACC0 $ACC0 \
|
|
||||||
# --private-key $PK0 \
|
|
||||||
# src/CIDStorage.sol:CIDStorage
|
|
|
@ -2,7 +2,6 @@
|
||||||
src = "src"
|
src = "src"
|
||||||
out = "out"
|
out = "out"
|
||||||
libs = ["lib"]
|
libs = ["lib"]
|
||||||
evm_version = "cancun"
|
|
||||||
|
|
||||||
[rpc_endpoints]
|
[rpc_endpoints]
|
||||||
sepolia = "${PROVIDER_URL}"
|
sepolia = "${PROVIDER_URL}"
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 5475f852e3f530d7e25dfb4596aa1f9baa8ffdfc
|
Subproject commit 36c303b7ffdd842d06b1ec2744c9b9b5fb3083f3
|
|
@ -1 +1 @@
|
||||||
Subproject commit 52c36d412e8681053975396223d0ea39687fe33b
|
Subproject commit 01ef448981be9d20ca85f2faf6ebdf591ce409f3
|
|
@ -3,7 +3,6 @@ pragma solidity ^0.8.23;
|
||||||
|
|
||||||
import {Script, console2} from "forge-std/Script.sol";
|
import {Script, console2} from "forge-std/Script.sol";
|
||||||
import { DappIndexer} from "src/DappIndexer.sol";
|
import { DappIndexer} from "src/DappIndexer.sol";
|
||||||
import { CIDStorage } from "src/CIDStorage.sol";
|
|
||||||
|
|
||||||
contract DappIndexerScript is Script {
|
contract DappIndexerScript is Script {
|
||||||
DappIndexer public dappIdxr;
|
DappIndexer public dappIdxr;
|
||||||
|
@ -20,41 +19,63 @@ contract DappIndexerScript is Script {
|
||||||
uint256 deployerPrivateKey = vm.envUint("PK0");
|
uint256 deployerPrivateKey = vm.envUint("PK0");
|
||||||
// startBroadcast and stopBraodcast will let us execute transactions anything between them
|
// startBroadcast and stopBraodcast will let us execute transactions anything between them
|
||||||
vm.startBroadcast(deployerPrivateKey);
|
vm.startBroadcast(deployerPrivateKey);
|
||||||
// here we just need to deploy a new contract
|
// here we just need to deploy a new contractc
|
||||||
dappIdxr = new DappIndexer(owner, owner);
|
dappIdxr = new DappIndexer(owner, owner);
|
||||||
console2.log("The Dapps Indexer contract address is: ", address(dappIdxr));
|
console2.log("The Dapps Indexer contract address is: ", address(dappIdxr));
|
||||||
|
|
||||||
// Define a Dapp name
|
|
||||||
bytes32 dapp_name = bytes32("Dapp01");
|
|
||||||
|
|
||||||
// Define DappURI splited into two bytes32 CIDs
|
|
||||||
bytes32 CID1;
|
bytes32 CID1;
|
||||||
bytes32 CID2;
|
bytes32 CID2;
|
||||||
|
|
||||||
(CID1, CID2) = CIDStorage.stringToBytes32Pair(dappsURI[0]);
|
(CID1, CID2) = stringToBytes32Pair(dappsURI[0]);
|
||||||
|
|
||||||
// Add Dapp
|
// Add Dapp
|
||||||
console2.log("-----Adding Dapp-----");
|
console2.log("-----Adding Dapp-----");
|
||||||
console2.log("Dapp Name is:");
|
console2.log("Dapp Name is:");
|
||||||
console2.logBytes32(dapp_name);
|
console2.logBytes32(bytes32("Dapp01"));
|
||||||
console2.log("Bytes32 first:");
|
console2.log("Bytes32 first:");
|
||||||
console2.logBytes32(CID1);
|
console2.logBytes32(CID1);
|
||||||
console2.log("Bytes32 second:");
|
console2.log("Bytes32 second:");
|
||||||
console2.logBytes32(CID2);
|
console2.logBytes32(CID2);
|
||||||
console2.log(CIDStorage.bytes32PairToString(CID1, CID2));
|
console2.log(Bytes32PairToString(CID1, CID2));
|
||||||
dappIdxr.addDapp(dapp_name, DappIndexer.PackedCID(CID1, CID2));
|
dappIdxr.addDapp(bytes32("Dapp01"), DappIndexer.PackedCID(CID1, CID2));
|
||||||
|
|
||||||
// retrive Dapp
|
// retrive Dapp
|
||||||
console2.log("-----retriving Dapp-----");
|
console2.log("-----retriving Dapp-----");
|
||||||
DappIndexer.PackedCID memory dapp1 = dappIdxr.getDapp(dapp_name);
|
DappIndexer.PackedCID memory dapp1 = dappIdxr.getDapp(bytes32("Dapp01"));
|
||||||
console2.log("Bytes32 first:");
|
console2.log("Bytes32 first:");
|
||||||
console2.logBytes32(dapp1.CID1);
|
console2.logBytes32(dapp1.CID1);
|
||||||
console2.log("Bytes32 second:");
|
console2.log("Bytes32 second:");
|
||||||
console2.logBytes32(dapp1.CID2);
|
console2.logBytes32(dapp1.CID2);
|
||||||
|
console2.log(Bytes32PairToString(dapp1.CID1, dapp1.CID2));
|
||||||
// reconstruct the CID and verify
|
|
||||||
console2.log(CIDStorage.bytes32PairToString(dapp1.CID1, dapp1.CID2));
|
|
||||||
|
|
||||||
vm.stopBroadcast();
|
vm.stopBroadcast();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Bytes32PairToString(bytes32 part1, bytes32 part2) public pure returns (string memory) {
|
||||||
|
// Concatenate the two bytes32 variables
|
||||||
|
bytes memory concatenatedBytes = abi.encodePacked(part1, part2);
|
||||||
|
|
||||||
|
// Truncate the concatenated bytes to 59 bytes
|
||||||
|
bytes memory truncatedBytes = new bytes(59);
|
||||||
|
for (uint i = 0; i < 59; i++) {
|
||||||
|
truncatedBytes[i] = concatenatedBytes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the truncated bytes to a string
|
||||||
|
string memory str = string(truncatedBytes);
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
function stringToBytes32Pair(string memory source) public pure returns (bytes32 part1, bytes32 part2) {
|
||||||
|
bytes memory sourceBytes = bytes(source);
|
||||||
|
require(sourceBytes.length == 59, "URI string must equal to 59 bytes");
|
||||||
|
|
||||||
|
assembly {
|
||||||
|
// Load the first 32 bytes of the string data
|
||||||
|
part1 := mload(add(sourceBytes, 32))
|
||||||
|
// Load the second 32 bytes of the string data
|
||||||
|
part2 := mload(add(sourceBytes, 64))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
// SPDX-License-Identifier: UNLICENSED
|
|
||||||
pragma solidity ^0.8.23;
|
|
||||||
|
|
||||||
import {Script, console2} from "forge-std/Script.sol";
|
|
||||||
import { DappIndexer} from "src/DappIndexer.sol";
|
|
||||||
import { CIDStorage } from "src/CIDStorage.sol";
|
|
||||||
|
|
||||||
contract DappIndexerScript is Script {
|
|
||||||
address public dappIndexerAddr;
|
|
||||||
address public CIDStorageAddr;
|
|
||||||
DappIndexer public dappIdxr;
|
|
||||||
string[] public dappsURI;
|
|
||||||
address public owner;
|
|
||||||
|
|
||||||
function setUp() public {
|
|
||||||
dappIndexerAddr = vm.envAddress("DAPPINDEXERADDRS");
|
|
||||||
dappsURI = vm.envString("dapps", ' ');
|
|
||||||
// Deployed contract must have Owner as ACC0)
|
|
||||||
owner = vm.envAddress("ACC0");
|
|
||||||
}
|
|
||||||
|
|
||||||
// run is the entry point
|
|
||||||
function run() public {
|
|
||||||
uint256 deployerPrivateKey = vm.envUint("PK0");
|
|
||||||
// startBroadcast and stopBraodcast will let us execute transactions anything between them
|
|
||||||
vm.startBroadcast(deployerPrivateKey);
|
|
||||||
// connect to the DappIndexer already deployed address
|
|
||||||
dappIdxr = DappIndexer(dappIndexerAddr);
|
|
||||||
|
|
||||||
console2.log("The Dapps Indexer contract address is: ", address(dappIdxr));
|
|
||||||
|
|
||||||
// Define a Dapp name
|
|
||||||
bytes32 dapp_name = bytes32("Dapp01");
|
|
||||||
|
|
||||||
// Define DappURI splited into two bytes32 CIDs
|
|
||||||
bytes32 CID1;
|
|
||||||
bytes32 CID2;
|
|
||||||
|
|
||||||
(CID1, CID2) = CIDStorage.stringToBytes32Pair(dappsURI[0]);
|
|
||||||
|
|
||||||
// Add Dapp
|
|
||||||
console2.log("-----Adding Dapp-----");
|
|
||||||
console2.log("Dapp Name is:");
|
|
||||||
console2.logBytes32(dapp_name);
|
|
||||||
console2.log("Bytes32 first:");
|
|
||||||
console2.logBytes32(CID1);
|
|
||||||
console2.log("Bytes32 second:");
|
|
||||||
console2.logBytes32(CID2);
|
|
||||||
console2.log(CIDStorage.bytes32PairToString(CID1, CID2));
|
|
||||||
dappIdxr.addDapp(dapp_name, DappIndexer.PackedCID(CID1, CID2));
|
|
||||||
|
|
||||||
// retrive Dapp
|
|
||||||
console2.log("-----retriving Dapp-----");
|
|
||||||
DappIndexer.PackedCID memory dapp1 = dappIdxr.getDapp(dapp_name);
|
|
||||||
console2.log("Bytes32 first:");
|
|
||||||
console2.logBytes32(dapp1.CID1);
|
|
||||||
console2.log("Bytes32 second:");
|
|
||||||
console2.logBytes32(dapp1.CID2);
|
|
||||||
|
|
||||||
// reconstruct the CID and verify
|
|
||||||
console2.log(CIDStorage.bytes32PairToString(dapp1.CID1, dapp1.CID2));
|
|
||||||
|
|
||||||
vm.stopBroadcast();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
// SPDX-License-Identifier: UNLICENSED
|
|
||||||
pragma solidity ^0.8.23;
|
|
||||||
|
|
||||||
library CIDStorage {
|
|
||||||
function bytes32PairToString(bytes32 part1, bytes32 part2) public pure returns (string memory) {
|
|
||||||
// Concatenate the two bytes32 variables
|
|
||||||
bytes memory concatenatedBytes = abi.encodePacked(part1, part2);
|
|
||||||
|
|
||||||
// Truncate the concatenated bytes to 59 bytes
|
|
||||||
bytes memory truncatedBytes = new bytes(59);
|
|
||||||
for (uint i = 0; i < 59; i++) {
|
|
||||||
truncatedBytes[i] = concatenatedBytes[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert the truncated bytes to a string
|
|
||||||
string memory str = string(truncatedBytes);
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
function stringToBytes32Pair(string memory source) public pure returns (bytes32 part1, bytes32 part2) {
|
|
||||||
bytes memory sourceBytes = bytes(source);
|
|
||||||
require(sourceBytes.length == 59, "URI string must equal to 59 bytes");
|
|
||||||
|
|
||||||
assembly {
|
|
||||||
// Load the first 32 bytes of the string data
|
|
||||||
part1 := mload(add(sourceBytes, 32))
|
|
||||||
// Load the second 32 bytes of the string data
|
|
||||||
part2 := mload(add(sourceBytes, 64))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,8 +14,6 @@ contract DappIndexer is AccessControl {
|
||||||
|
|
||||||
mapping (bytes32 => PackedCID) private dapps;
|
mapping (bytes32 => PackedCID) private dapps;
|
||||||
|
|
||||||
bytes32[] public dapp_names;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
address defaultAdmin,
|
address defaultAdmin,
|
||||||
address moderator
|
address moderator
|
||||||
|
@ -26,49 +24,14 @@ contract DappIndexer is AccessControl {
|
||||||
|
|
||||||
function addDapp(bytes32 dapp_name, PackedCID calldata cid)
|
function addDapp(bytes32 dapp_name, PackedCID calldata cid)
|
||||||
external onlyRole(MODERATOR_ROLE) {
|
external onlyRole(MODERATOR_ROLE) {
|
||||||
//if the struct does not exists trace it on the array
|
|
||||||
if (dapps[dapp_name].CID1 != 0 && dapps[dapp_name].CID2 != 0) {
|
|
||||||
dapp_names.push(dapp_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
dapps[dapp_name] = PackedCID(cid.CID1, cid.CID2);
|
dapps[dapp_name] = PackedCID(cid.CID1, cid.CID2);
|
||||||
}
|
}
|
||||||
|
|
||||||
//@Notice: consider calling getDappIndex internal and pop dapps and dapp_names
|
function removeDapp(bytes32 dapp_name) external onlyRole(MODERATOR_ROLE) {
|
||||||
//@Notice: Yet requiring index might give extra verification
|
|
||||||
function removeDapp(uint index, bytes32 dapp_name)
|
|
||||||
external onlyRole(MODERATOR_ROLE) {
|
|
||||||
require(index < dapp_names.length, "dapp index out of bounds");
|
|
||||||
require(dapp_names[index] == dapp_name);
|
|
||||||
dapp_names[index] = dapp_names[dapp_names.length - 1];
|
|
||||||
dapp_names.pop();
|
|
||||||
delete dapps[dapp_name];
|
delete dapps[dapp_name];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDapp(bytes32 dapp_name) external view returns (PackedCID memory){
|
function getDapp(bytes32 dapp_name) external view returns (PackedCID memory){
|
||||||
return dapps[dapp_name];
|
return dapps[dapp_name];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDappIndex(bytes32 dapp_name) external view returns (uint256 i) {
|
|
||||||
require(dappExists(dapp_name));
|
|
||||||
for(i; i <= dapp_names.length; i++){
|
|
||||||
if(dapp_names[i] == dapp_name){
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function listDappNames() external view returns (bytes32[] memory) {
|
|
||||||
return dapp_names;
|
|
||||||
}
|
|
||||||
|
|
||||||
function dappExists(bytes32 dapp_name) public view returns (bool) {
|
|
||||||
for(uint i; i <= dapp_names.length; i++){
|
|
||||||
if(dapp_names[i] == dapp_name){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,69 +3,64 @@ pragma solidity ^0.8.23;
|
||||||
|
|
||||||
import { Test, console2 } from "forge-std/Test.sol";
|
import { Test, console2 } from "forge-std/Test.sol";
|
||||||
import { DappIndexer } from "src/DappIndexer.sol";
|
import { DappIndexer } from "src/DappIndexer.sol";
|
||||||
import { CIDStorage } from "src/CIDStorage.sol";
|
|
||||||
|
|
||||||
contract DappIndexerTest is Test {
|
contract DappIndexerTest is Test {
|
||||||
DappIndexer public dappIdxr;
|
DappIndexer public dappIdxr;
|
||||||
string[] public dappsURI;
|
string[] public dappsURI;
|
||||||
address public owner;
|
|
||||||
|
|
||||||
function setUp() public {
|
function setUp() public {
|
||||||
dappIdxr = new DappIndexer(address(this), address(this));
|
dappIdxr = new DappIndexer(address(this), address(this));
|
||||||
dappsURI = vm.envString("dapps", ' ');
|
dappsURI = vm.envString("dapps", ' ');
|
||||||
owner = vm.envAddress("ACC0");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test adding a dapp that doesn't exist
|
|
||||||
function testAddDapp() public {
|
function testAddDapp() public {
|
||||||
bytes32 dapp_name = bytes32("Dapp01");
|
|
||||||
bytes32 CID1;
|
bytes32 CID1;
|
||||||
bytes32 CID2;
|
bytes32 CID2;
|
||||||
|
|
||||||
(CID1, CID2) = CIDStorage.stringToBytes32Pair(dappsURI[0]);
|
(CID1, CID2) = stringToBytes32Pair(dappsURI[0]);
|
||||||
|
|
||||||
// Add Dapp
|
// Add Dapp
|
||||||
console2.log("Dapp Name is:");
|
console2.log("Dapp Name is:");
|
||||||
console2.logBytes32(dapp_name);
|
console2.logBytes32(bytes32("Dapp01"));
|
||||||
console2.log("Bytes32 first:");
|
console2.log("Bytes32 first:");
|
||||||
console2.logBytes32(CID1);
|
console2.logBytes32(CID1);
|
||||||
console2.log("Bytes32 second:");
|
console2.log("Bytes32 second:");
|
||||||
console2.logBytes32(CID2);
|
console2.logBytes32(CID2);
|
||||||
console2.log(CIDStorage.bytes32PairToString(CID1, CID2));
|
console2.log(Bytes32PairToString(CID1, CID2));
|
||||||
dappIdxr.addDapp(dapp_name, DappIndexer.PackedCID(CID1, CID2));
|
dappIdxr.addDapp(bytes32("Dapp01"), DappIndexer.PackedCID(CID1, CID2));
|
||||||
|
|
||||||
// retrive Dapp
|
// retrive Dapp
|
||||||
DappIndexer.PackedCID memory dapp1 = dappIdxr.getDapp(dapp_name);
|
DappIndexer.PackedCID memory dapp1 = dappIdxr.getDapp(bytes32("Dapp01"));
|
||||||
assertEq(CID1, dapp1.CID1);
|
assertEq(CID1, dapp1.CID1);
|
||||||
assertEq(CID2, dapp1.CID2);
|
assertEq(CID2, dapp1.CID2);
|
||||||
|
string memory retrivedDappURI = Bytes32PairToString(dapp1.CID1, dapp1.CID2);
|
||||||
// reconstruct the CID and verify
|
|
||||||
string memory retrivedDappURI = CIDStorage.bytes32PairToString(dapp1.CID1, dapp1.CID2);
|
|
||||||
assertEq(dappsURI[0], retrivedDappURI);
|
assertEq(dappsURI[0], retrivedDappURI);
|
||||||
}
|
}
|
||||||
|
|
||||||
//## ToDo ISSUE #2
|
function Bytes32PairToString(bytes32 part1, bytes32 part2) public pure returns (string memory) {
|
||||||
//
|
// Concatenate the two bytes32 variables
|
||||||
//### Features testing
|
bytes memory concatenatedBytes = abi.encodePacked(part1, part2);
|
||||||
//
|
|
||||||
//- [x] test adding a dapp and retrive it. (addDapp, getDapp)
|
|
||||||
//
|
|
||||||
//- [ ] test removing a dapp that exists (verify dapps and dapp_names)
|
|
||||||
//- [ ] test dappExists (lower, upper, fuzz)
|
|
||||||
//- [ ] test removing a dapp that doesn't exist
|
|
||||||
//- [ ] test getting that names (listDappNames)
|
|
||||||
//- [ ] test getDappIndex (lower, upper, fuzz)
|
|
||||||
//- [ ] check if dapp name exists
|
|
||||||
//
|
|
||||||
//### Library testing
|
|
||||||
//
|
|
||||||
//- [ ] test adding longer CID
|
|
||||||
//- [ ] test adding shorter CID
|
|
||||||
//- [ ] test fuzz
|
|
||||||
//
|
|
||||||
//### Testing Roles Open Zeppelin Module
|
|
||||||
//
|
|
||||||
//- [ ] test roles for educational purposes.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
// Truncate the concatenated bytes to 59 bytes
|
||||||
|
bytes memory truncatedBytes = new bytes(59);
|
||||||
|
for (uint i = 0; i < 59; i++) {
|
||||||
|
truncatedBytes[i] = concatenatedBytes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the truncated bytes to a string
|
||||||
|
string memory str = string(truncatedBytes);
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
function stringToBytes32Pair(string memory source) public pure returns (bytes32 part1, bytes32 part2) {
|
||||||
|
bytes memory sourceBytes = bytes(source);
|
||||||
|
require(sourceBytes.length == 59, "URI string must equal to 59 bytes");
|
||||||
|
|
||||||
|
assembly {
|
||||||
|
// Load the first 32 bytes of the string data
|
||||||
|
part1 := mload(add(sourceBytes, 32))
|
||||||
|
// Load the second 32 bytes of the string data
|
||||||
|
part2 := mload(add(sourceBytes, 64))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
// SPDX-License-Identifier: UNLICENSED
|
||||||
|
pragma solidity ^0.8.23;
|
||||||
|
|
||||||
|
import { Test, console2 } from "forge-std/Test.sol";
|
||||||
|
import { DappIndexer } from "src/DappIndexer.sol";
|
||||||
|
|
||||||
|
contract DappIndexerTest is Test {
|
||||||
|
DappIndexer public dappIdxr;
|
||||||
|
string[] public dappsURI;
|
||||||
|
|
||||||
|
function setUp() public {
|
||||||
|
dappIdxr = new DappIndexer(address(this), address(this));
|
||||||
|
dappsURI = vm.envString("dapps", ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testAddDapp() public {
|
||||||
|
bytes32 CID1;
|
||||||
|
bytes32 CID2;
|
||||||
|
|
||||||
|
//(CID1, CID2) = stringToBytes32Pair(dappsURI[0]);
|
||||||
|
string memory dapp= "bafkreibc6p3y36yjmeqqnttqfrpb2yttxa6aonoywxwdxl7nqym4jj3jwa";
|
||||||
|
(CID1, CID2) = stringToBytes32Pair(dapp);
|
||||||
|
|
||||||
|
// Add Dapp
|
||||||
|
console2.log("Bytes32 first:");
|
||||||
|
console2.logBytes32(CID1);
|
||||||
|
console2.log("Bytes32 second:");
|
||||||
|
console2.logBytes32(CID2);
|
||||||
|
console2.log(Bytes32PairToString(CID1, CID2));
|
||||||
|
dappIdxr.addDapp(bytes32("Dapp01"), DappIndexer.PackedCID(CID1, CID2));
|
||||||
|
// retrive Dapp
|
||||||
|
DappIndexer.PackedCID memory dapp1 = dappIdxr.getCID(bytes32("Dapp01"));
|
||||||
|
assertEq(CID1, dapp1.CID1);
|
||||||
|
assertEq(CID2, dapp1.CID2);
|
||||||
|
assertEq(dappsURI[0], Bytes32PairToString(dapp1.CID1, dapp1.CID2));
|
||||||
|
}
|
||||||
|
|
||||||
|
function Bytes32PairToString(bytes32 part1, bytes32 part2) public pure returns (string memory) {
|
||||||
|
// Concatenate the two bytes32 variables
|
||||||
|
bytes memory concatenatedBytes = abi.encodePacked(part1, part2);
|
||||||
|
|
||||||
|
// Convert the concatenated bytes to a string
|
||||||
|
string memory str = string(concatenatedBytes);
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
function stringToBytes32Pair(string memory source) public pure returns (bytes32 part1, bytes32 part2) {
|
||||||
|
bytes memory sourceBytes = bytes(source);
|
||||||
|
require(sourceBytes.length == 59, "Source string must be 59 bytes");
|
||||||
|
|
||||||
|
assembly {
|
||||||
|
// Load the first 32 bytes of the string data
|
||||||
|
part1 := mload(add(sourceBytes, 32))
|
||||||
|
// Load the next 32 bytes of the string data, then shift right by 3 bytes (24 bits) to remove unwanted bytes
|
||||||
|
part2 := mload(add(sourceBytes, 64))
|
||||||
|
part2 := shl(24, part2) // Shift left to remove the last 5 bytes
|
||||||
|
part2 := shr(24, part2) // Shift right to align back to the least significant bits
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//function stringToBytes32Pair(string memory source) public pure returns (bytes32 part1, bytes32 part2) {
|
||||||
|
// bytes memory sourceBytes = bytes(source);
|
||||||
|
// require(sourceBytes.length == 59, "URI string must equal to 59 bytes");
|
||||||
|
|
||||||
|
// assembly {
|
||||||
|
// // Load the first 32 bytes of the string data
|
||||||
|
// part1 := mload(add(sourceBytes, 32))
|
||||||
|
// // Load the second 32 bytes of the string data
|
||||||
|
// part2 := mload(add(sourceBytes, 58))
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
// function stringToBytes32Pair(string calldata str) external pure returns(bytes32 part1, bytes32 part2) {
|
||||||
|
// bytes memory sourceBytes = bytes(str);
|
||||||
|
// require(sourceBytes.length == 59, "Source string must be 59 bytes");
|
||||||
|
// part1 = bytes(str[0:32]);
|
||||||
|
// part2 = bytes(str[32:59]);
|
||||||
|
//
|
||||||
|
// return (part1, part2);
|
||||||
|
// }
|
Loading…
Reference in New Issue