Skip to content

Commit

Permalink
Add deploy UniversalFactory code
Browse files Browse the repository at this point in the history
  • Loading branch information
YamenMerhi committed Jul 23, 2024
1 parent 68a9146 commit 6936861
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 0 deletions.
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();

0 comments on commit 6936861

Please sign in to comment.