Skip to content
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

Add support for data encoding with unit tests and update Solidity interfaces #1

Merged
merged 55 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
c3ee7c7
change test file extension to .test.ts to prevent jest No tests found…
najienka Jan 6, 2025
170036c
add ganache integration for local blockchain integration tests and sa…
najienka Jan 6, 2025
0aa5e95
fix linting
najienka Jan 6, 2025
e61d5e5
rename ganache test to integration test
najienka Jan 6, 2025
47258ba
remove unused comment
najienka Jan 15, 2025
82029f6
add support for data encoding
najienka Jan 16, 2025
fdeaf6a
restructure contracts folder
najienka Jan 17, 2025
d420315
update solidity contracts and blocklock js constructor
najienka Jan 17, 2025
1a676d8
update unit tests
najienka Jan 17, 2025
a1bd3a6
update tests
najienka Jan 17, 2025
a26b749
separate encoder and decoder
najienka Jan 20, 2025
d668b98
switch to yarn in build.yml
najienka Jan 20, 2025
998e962
add build:generate for BlocklockSender.sol
najienka Jan 20, 2025
d0b90b4
add mock blocklock receiver for end to end testing
najienka Jan 20, 2025
2dec667
update function name
najienka Jan 20, 2025
4683573
update test case descriptions
najienka Jan 21, 2025
7b0939c
encode to uint8Array and decode
najienka Jan 21, 2025
d864b6d
remove console log
najienka Jan 21, 2025
fff5106
explicitly name contract address required in blocklock constructor
najienka Jan 21, 2025
b966f25
increase jest timeout for blockchain integration tests
najienka Jan 21, 2025
216d054
fix integration test and bug in user blocklock receiver contract
najienka Jan 21, 2025
29ce323
remove solidity build folder from gitignore
najienka Jan 21, 2025
bb7a513
update yarn build
najienka Jan 21, 2025
bd073ed
add the option of blocklock public key in constructor with blocklock …
najienka Jan 22, 2025
1c1648b
fix linting
najienka Jan 22, 2025
2ca04e4
remove signature sender smart contract deployment from tests
najienka Jan 22, 2025
a277d53
update user smart contract
najienka Jan 22, 2025
b771be8
update index.ts imports
najienka Jan 22, 2025
89665e3
update imports
najienka Jan 22, 2025
c333bf6
update readme file
najienka Jan 22, 2025
1c5d447
Update README.md
najienka Jan 22, 2025
5c1fbc1
Update README.md
najienka Jan 22, 2025
5847dcd
Update README.md
najienka Jan 22, 2025
df45db0
Update README.md
najienka Jan 22, 2025
9c1df7a
Update README.md
najienka Jan 22, 2025
116d8d0
local readme
najienka Jan 22, 2025
c439a47
update readme
najienka Jan 22, 2025
da7d8d8
add blocklock sender contract address to docs
najienka Jan 23, 2025
1060238
update solidity code and ibe lib
najienka Jan 23, 2025
c87d85d
udpate readme
najienka Jan 23, 2025
9139270
update contract address
najienka Jan 23, 2025
2007a31
update contracts readme
najienka Jan 24, 2025
6a90719
remove contracts readme
najienka Jan 24, 2025
dcb85d4
move blskey to .env
najienka Jan 24, 2025
c6d184d
update git action with env
najienka Jan 24, 2025
bd4be26
update identityFromEncodedConditions
najienka Jan 24, 2025
45ebe92
Update README.md
najienka Jan 24, 2025
fb7f262
Update README.md
najienka Jan 24, 2025
5ae92a0
use ethers.js data types
najienka Jan 24, 2025
b8feccb
Merge branch 'refactoring' of https://github.com/randa-mu/blocklock-j…
najienka Jan 24, 2025
4472c79
update docs
najienka Jan 24, 2025
cfc6b50
Update README.md
najienka Jan 24, 2025
d2e3580
Update contracts/src/mocks/MockBlocklockReceiver.sol
najienka Jan 24, 2025
3aaa78f
Update contracts/src/mocks/MockBlocklockReceiver.sol
najienka Jan 24, 2025
c21a3f6
Update contracts/src/mocks/MockBlocklockReceiver.sol
najienka Jan 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ jobs:
node-version: 22.3.0

- name: Install dependencies
run: npm ci
run: yarn install

- name: Test
run: npm run test
run: yarn test

- name: Build
run: npm run build
run: yarn build
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "contracts/lib/forge-std"]
path = contracts/lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "contracts/lib/openzeppelin-contracts"]
path = contracts/lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
129 changes: 124 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,129 @@
## @randamu/blocklock-js

A convenience library for encrypting data for the dcrypt network to dcrypt based on conditions you set.
BlocklockJS is a TypeScript library designed to simplify the process of generating encrypted data off-chain for the dcrypt network. It enables developers to securely encrypt data tied to a user-specified future block number. The encrypted data can then be used to create on-chain timelock encryption requests in smart contracts. Once the specified block number is mined, the user’s smart contract will receive the decryption keys automatically.

Build everything by running `npm run build`. This creates an `index.js` and `index.d.ts` at the root directory.

Solidity interfaces for encryption and decryption can be found in the [contracts](./contracts) directory.
### Key Capabilities

## Documentation
You can find the docs [on our docs website](https://dcrypt.network/docs/features/blocklock)
Using this library, developers can:

* Encode and encrypt various Solidity-compatible data types.
* Encrypt the encoded data off-chain using a public key, which can then be integrated into smart contracts for timelock encryption requests.


### On-Chain Integration

Solidity interfaces used for on-chain decryption requests can be found in the [contracts](./contracts) directory and the documentation for the solidity interfaces can be found in the [blocklock-solidity](github.com/randa-mu/blocklock-solidity.git) repository.

#### Smart Contract Addresses

| Contract | Address | Network |
|-----------------|---------|------------------|
| BlocklockSender Proxy | 0xfF66908E1d7d23ff62791505b2eC120128918F44 | Filecoin Testnet |


### Build Instructions

To build the library, run the following command:

```sh
npm run build
```

This creates an `index.js` and `index.d.ts` at the root directory.

### Usage Example

Here’s how to use BlocklockJS to encrypt data and create an on-chain timelock encryption request.

#### Example: Encrypting a uint256 (4 ETH) for Decryption 2 Blocks Later

This example demonstrates encrypting a uint256 value and sending it to a user smart contract that implements the createTimelockRequest function. In a different use case, e.g., sealed bid auction, this could be refactored into a `sealedBid` function.
The example user smart contract source code can be found [here](contracts/src/mocks/MockBlocklockReceiver.sol).

```js
import { ethers, getBytes } from "ethers";
import { Blocklock, SolidityEncoder, encodeCiphertextToSolidity } from "blocklockjs";
import { MockBlocklockReceiver__factory } from "../types"; // Generated by Typechain
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mockblocklock - sounds funny ;p

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking for consistency with our website and blogs, we might need to stop using the name blocklock and use timelock throughout in all our code bases.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I think this makes sense - the time vs chainheight differentiation for drand vs decrypt won’t matter for most users

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I've added to the list of items for the next release.


async function main() {
// User wallet
const wallet = new ethers.Wallet("your-private-key", ethers.provider);
// User contract
const mockBlocklockReceiver = MockBlocklockReceiver__factory.connect("user blocklcok receiver contract address", wallet);

// Ensure plainTextValue is initially 0
console.log("Initial plainTextValue:", (await mockBlocklockReceiver.plainTextValue()).toString());

// Set block height (current block + 2)
const blockHeight = BigInt(await ethers.provider.getBlockNumber() + 2);

// Value to encrypt (4 ETH as uint256)
const msg = ethers.utils.parseEther("4");

// Encode the uint256 value
const encoder = new SolidityEncoder();
const msgBytes = encoder.encodeUint256(msg);
const encodedMessage = getBytes(msgBytes);

// Encrypt the encoded message
const blocklockjs = new Blocklock(wallet, "blocklockSender contract address");
const ciphertext = blocklockjs.encrypt(encodedMessage, blockHeight);

// Call `createTimelockRequest` on the user's contract
const tx = await mockBlocklockReceiver
.connect(wallet)
.createTimelockRequest(blockHeight, encodeCiphertextToSolidity(ciphertext));
const receipt = await tx.wait(1);

if (!receipt) {
throw new Error("Transaction has not been mined");
}

console.log("Timelock request created!");
}

main().catch((error) => {
console.error("Error:", error);
});
```

#### How It Works
1. Encoding and Encryption:

* Use the SolidityEncoder to encode Solidity-compatible data types.
* Encrypt the encoded message and specify the decryption block number.

2. On-Chain Interaction:

* Call the appropriate function in the user contract with the encrypted data and the block number used during off-chain encryption. In this example, the function `createTimelockRequest` is called, which creates an on-chain timelock request with the encrypted data and block number as a condition for decryption, stores the encrypted data, and generates a request ID.

3. Decryption:

* After the specified block number, the on-chain timelock contract triggers a callback to the user's contract, providing the decryption key. The user's contract then calls the `decrypt` function in the `BlocklockSender` contract to perform on-chain decryption using the provided decryption key.


### Supported Data Types
The library supports encoding and encryption of the following Solidity-compatible data types:

* uint256
* int256
* address
* string
* bytes
* bytes32

Use the `SolidityEncoder` to encode any of these types before encryption.


### Licensing

This library is licensed under the MIT License which can be accessed [here](LICENSE).

### Contributing

Contributions are welcome! If you find a bug, have a feature request, or want to improve the code, feel free to open an issue or submit a pull request.

### Acknowledgments

Special thanks to the Filecoin Foundation for supporting the development of this library.
66 changes: 0 additions & 66 deletions contracts/README.md

This file was deleted.

1 change: 1 addition & 0 deletions contracts/lib/openzeppelin-contracts
Submodule openzeppelin-contracts added at acd4ff
17 changes: 11 additions & 6 deletions contracts/src/AbstractBlocklockReceiver.sol
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import {IBlocklockReceiver} from "./IBlocklockReceiver.sol";
import {IBlocklockReceiver} from "./interfaces/IBlocklockReceiver.sol";
import {IBlocklockSender} from "./interfaces/IBlocklockSender.sol";

abstract contract AbstractBlocklockReceiver is IBlocklockReceiver {
address public immutable DECRYPTION_PROVIDER = 0x11045878Ed62Ec3aCC91cE36A46F4EF61d4616e1;
IBlocklockSender public blocklock;

error NotAuthorizedDecryptionProvider();

modifier onlyDecryptionProvider(){
if (msg.sender != DECRYPTION_PROVIDER) revert NotAuthorizedDecryptionProvider();
modifier onlyBlocklockContract() {
require(msg.sender == address(blocklock), "Only timelock contract can call this.");
_;
}

constructor(address blocklockSender) {
blocklock = IBlocklockSender(blocklockSender);
}

function receiveBlocklock(uint256 requestID, bytes calldata decryptionKey) external virtual onlyBlocklockContract {}
}
15 changes: 0 additions & 15 deletions contracts/src/AbstractDecryptionReceiver.sol

This file was deleted.

63 changes: 0 additions & 63 deletions contracts/src/Blocklock.sol

This file was deleted.

12 changes: 0 additions & 12 deletions contracts/src/IDecryptionReceiver.sol

This file was deleted.

Loading
Loading