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 deploy LSP16UniversalFactory code #62

Merged
merged 1 commit into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions universal-factory/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Deploy Multichain Contracts

- https://docs.lukso.tech/learn/other-guides/deploy-multichain-contracts
42 changes: 42 additions & 0 deletions universal-factory/TargetContract.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"abi": [
{
"inputs": [
{
"internalType": "uint256",
"name": "_number",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "number",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_number",
"type": "uint256"
}
],
"name": "setNumber",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"bytecode": "0x608060405234801561001057600080fd5b5060405161010f38038061010f83398101604081905261002f91610037565b600055610050565b60006020828403121561004957600080fd5b5051919050565b60b18061005e6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c80633fb5c1cb1460375780638381f58a146049575b600080fd5b604760423660046063565b600055565b005b605160005481565b60405190815260200160405180910390f35b600060208284031215607457600080fd5b503591905056fea2646970667358221220958426080fb00e4b3e137866f9d1884559c2a31f2d3ee15cd4f2c8aee4a92e6764736f6c63430008110033"
}
23 changes: 23 additions & 0 deletions universal-factory/check-universal-factory-exist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ethers } from 'ethers';

const RPC_URL = 'https://rpc.testnet.lukso.network';
const provider = new ethers.JsonRpcProvider(RPC_URL);

const checkDeployedCode = async (address: any) => {
const code = await provider.getCode(address);
return code !== '0x';
};

// Fixed addresses

// For more information check: https://github.com/Arachnid/deterministic-deployment-proxy
const NICK_FACTORY_ADDRESS = '0x4e59b44847b379578588920ca78fbf26c0b4956c';

// For more information check: https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-16-UniversalFactory.md
const LSP16_FACTORY_ADDRESS = '0x1600016e23e25D20CA8759338BfB8A8d11563C4e';

const isNickFactoryDeployed = await checkDeployedCode(NICK_FACTORY_ADDRESS);
const isLSP16FactoryDeployed = await checkDeployedCode(LSP16_FACTORY_ADDRESS);

console.log('Nick Factory exists: ', isNickFactoryDeployed);
console.log('LSP16UniversalFactory exists: ', isLSP16FactoryDeployed);
66 changes: 66 additions & 0 deletions universal-factory/deploy-contract.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { ethers } from 'ethers';

const RPC_URL = 'https://rpc.testnet.lukso.network';
const provider = new ethers.JsonRpcProvider(RPC_URL);

import { abi as LSP16UniversalFactoryABI } from '@lukso/lsp-smart-contracts/artifacts/LSP16UniversalFactory.json';
import {
abi as TargetContractABI,
bytecode as targetContractBytecode,
} from './TargetContract.json';

// The private key should not be comitted to a public GitHub repository.
const signer = new ethers.Wallet('<private-key>', provider);

// For more information check: https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-16-UniversalFactory.md
const LSP16_FACTORY_ADDRESS = '0x1600016e23e25D20CA8759338BfB8A8d11563C4e';

const lsp16UniversalFactory = new ethers.Contract(
LSP16_FACTORY_ADDRESS,
LSP16UniversalFactoryABI,
signer,
);

// Dummy value
const constructorArgument = 123;
const encodedConstructorArg = ethers.AbiCoder.defaultAbiCoder().encode(
['uint256'],
[constructorArgument],
);

const contractBytecodeWithArg =
targetContractBytecode + encodedConstructorArg.substring(2);

// On each script run, this salt should be different otherwise the deployment will fail
// Don't use random bytes as salt, use a deterministic salt to be able to deploy on a different network
// using the same salt, to produce the same address
// Should be a hex string like 0x1322322... (32 bytes)
const deploymentSalt = '<bytes32-salt>';

// Precompute the address of the contract to be deployed without initialization
const precomputedAddressWithoutInit =
await lsp16UniversalFactory.computeAddress(
ethers.keccak256(contractBytecodeWithArg),
deploymentSalt,
false, // --> boolean indicating if the contract should be initialized or not after deployment
'0x', // --> bytes representing the calldata to initialize the contract
);

// Deploy contract without initialization
const deployTxWithoutInit = await lsp16UniversalFactory.deployCreate2(
contractBytecodeWithArg,
deploymentSalt,
);
await deployTxWithoutInit.wait();

const contractWithoutInit = new ethers.Contract(
precomputedAddressWithoutInit,
TargetContractABI,
signer,
);

const numberInContractWithoutInit = await contractWithoutInit.number();
console.log(
'The number in the non-initialized contract is: ',
numberInContractWithoutInit,
);
23 changes: 23 additions & 0 deletions universal-factory/deploy-nick-factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ethers } from 'ethers';

const RPC_URL = 'https://rpc.testnet.lukso.network';
const provider = new ethers.JsonRpcProvider(RPC_URL);

// The private key should not be comitted to a public GitHub repository.
const signer = new ethers.Wallet('<private-key>', provider);

const fundingTx = await signer.sendTransaction({
// Standardized address
to: '0x3fab184622dc19b6109349b94811493bf2a45362',
value: ethers.parseEther('0.009'), // This value should be enough
// Check gasLimit and gasPrice to estimate exactly the value: https://github.com/Arachnid/deterministic-deployment-proxy
});

await fundingTx.wait();

// Sending raw transaction specified by the Nick factory
const rawTx =
'0xf8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222';

const deployNickFactoryTx = await provider.broadcastTransaction(rawTx);
await deployNickFactoryTx.wait();
17 changes: 17 additions & 0 deletions universal-factory/deploy-universal-factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { ethers } from 'ethers';

const RPC_URL = 'https://rpc.testnet.lukso.network';
const provider = new ethers.JsonRpcProvider(RPC_URL);

// The private key should not be comitted to a public GitHub repository.
const signer = new ethers.Wallet('<private-key>', provider);

const lsp16Tx = await signer.sendTransaction({
to: '0x4e59b44847b379578588920ca78fbf26c0b4956c', // Nick Factory Address
data:
'0xfaee762dee0012026f5380724e9744bdc5dd26ecd8f584fe9d72a4170d01c049' + // Standardized Salt
'60806040523480156100105...', // Standardized Bytecode
// Copy the full bytecode from https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-16-UniversalFactory.md#standardized-bytecode
});

await lsp16Tx.wait();