From 61a74636d13123e2f2a954e6f622e7a262beb370 Mon Sep 17 00:00:00 2001 From: emochka2007 Date: Mon, 20 May 2024 02:22:57 +0300 Subject: [PATCH] deploy license finished --- .../license/license.controller.ts | 7 +- .../contract-interact/license/license.dto.ts | 1 + .../license/license.service.ts | 69 +++++++++++-------- .../multi-sig/multi-sig.service.ts | 39 +++++++---- chain-api/src/filters/http.filter.ts | 1 - chain-api/src/hardhat/contracts/License.sol | 4 +- .../src/hardhat/contracts/MultiSigWallet.sol | 41 ++++++++--- 7 files changed, 105 insertions(+), 57 deletions(-) diff --git a/chain-api/src/contract-interact/license/license.controller.ts b/chain-api/src/contract-interact/license/license.controller.ts index 502c70a..2c1b84e 100644 --- a/chain-api/src/contract-interact/license/license.controller.ts +++ b/chain-api/src/contract-interact/license/license.controller.ts @@ -3,6 +3,7 @@ import { LicenseService } from './license.service'; import { ApiTags } from '@nestjs/swagger'; import { DeployLicenseDto, + GetLicenseInfoDto, GetShareLicense, RequestLicenseDto, } from './license.dto'; @@ -10,7 +11,7 @@ import { @Controller('license') export class LicenseController { constructor(private readonly licenseService: LicenseService) {} - @Get('request') + @Post('request') async getLicenseRequest(@Body() dto: RequestLicenseDto) { return this.licenseService.request(dto); } @@ -21,7 +22,7 @@ export class LicenseController { } @Get('total-payout') - async getLicenseResponse(@Body() dto: RequestLicenseDto) { + async getLicenseResponse(@Body() dto: GetLicenseInfoDto) { return this.licenseService.getTotalPayoutInUSD(dto); } @@ -31,7 +32,7 @@ export class LicenseController { } @Get('owners') - async getOwners(@Body() dto: GetShareLicense) { + async getOwners(@Body() dto: GetLicenseInfoDto) { return this.licenseService.getOwners(dto); } diff --git a/chain-api/src/contract-interact/license/license.dto.ts b/chain-api/src/contract-interact/license/license.dto.ts index f3422cf..72ac255 100644 --- a/chain-api/src/contract-interact/license/license.dto.ts +++ b/chain-api/src/contract-interact/license/license.dto.ts @@ -33,5 +33,6 @@ export class GetLicenseResponseDto extends GetLicenseInfoDto {} export class GetShareLicense extends GetLicenseInfoDto { @IsString() + @ApiProperty() ownerAddress: string; } diff --git a/chain-api/src/contract-interact/license/license.service.ts b/chain-api/src/contract-interact/license/license.service.ts index 9cb8484..210ba78 100644 --- a/chain-api/src/contract-interact/license/license.service.ts +++ b/chain-api/src/contract-interact/license/license.service.ts @@ -35,7 +35,7 @@ export class LicenseService extends BaseContractService { }); } - async getTotalPayoutInUSD(dto: GetLicenseResponseDto) { + async getTotalPayoutInUSD(dto: GetLicenseInfoDto) { const { contractAddress } = dto; const { abi } = await hre.artifacts.readArtifact( 'StreamingRightsManagement', @@ -44,7 +44,7 @@ export class LicenseService extends BaseContractService { const contract = new ethers.Contract(contractAddress, abi, signer); - const answer: bigint = await contract.totalPayoutInUSD(); + const answer: bigint = await contract.request(); console.log('=>(license.service.ts:45) answer', answer); return answer.toString(); } @@ -57,23 +57,36 @@ export class LicenseService extends BaseContractService { ); const signer = await this.providerService.getSigner(); - const licenseContract = new ethers.ContractFactory(abi, bytecode, signer); + const abiCoder = ethers.AbiCoder.defaultAbiCoder(); - const myContract = await licenseContract.getDeployTransaction( - CHAINLINK.AMOY.CHAINLINK_TOKEN, - CHAINLINK.AMOY.ORACLE_ADDRESS, - CHAINLINK.AMOY.JOB_IDS.UINT, - 0, - multiSigWallet, - owners, - shares, - payrollAddress, + const abiEncodedConstructorArguments = abiCoder.encode( + [ + 'address', + 'address', + 'string', + 'uint', + 'address', + 'address[]', + 'uint[]', + 'address', + ], + [ + CHAINLINK.AMOY.CHAINLINK_TOKEN, + CHAINLINK.AMOY.ORACLE_ADDRESS, + CHAINLINK.AMOY.JOB_IDS.UINT, + 0, + multiSigWallet, + owners, + shares, + payrollAddress, + ], ); + const fullBytecode = bytecode + abiEncodedConstructorArguments.substring(2); const submitData = await this.multiSigService.submitTransaction({ contractAddress: multiSigWallet, destination: null, value: '0', - data: myContract.data, + data: fullBytecode, }); delete submitData.data; return submitData; @@ -102,9 +115,20 @@ export class LicenseService extends BaseContractService { const contract = new ethers.Contract(contractAddress, abi, signer); - const answer: string[] = await contract.owners(); + const owners: string[] = []; - return answer; + for (let i = 0; i < 10; i++) { + try { + const owner = await contract.owners(i); + owners.push(owner); + } catch (e) { + // this.logger.error(e); + console.log('OWNERS LIMIT'); + break; + } + } + + return owners; } async getShares(dto: GetShareLicense) { @@ -117,20 +141,7 @@ export class LicenseService extends BaseContractService { const contract = new ethers.Contract(contractAddress, abi, signer); const answer: number = await contract.getShare(ownerAddress); - - return answer; - } - - async getTotalPayout(dto: GetLicenseInfoDto) { - const { contractAddress } = dto; - const { abi } = await hre.artifacts.readArtifact( - 'StreamingRightsManagement', - ); - const signer = await this.providerService.getSigner(); - - const contract = new ethers.Contract(contractAddress, abi, signer); - - const answer: number = await contract.totalPayoutInUSD(); + console.log('=>(license.service.ts:135) answer', answer); return answer; } diff --git a/chain-api/src/contract-interact/multi-sig/multi-sig.service.ts b/chain-api/src/contract-interact/multi-sig/multi-sig.service.ts index 2545073..1b7c25a 100644 --- a/chain-api/src/contract-interact/multi-sig/multi-sig.service.ts +++ b/chain-api/src/contract-interact/multi-sig/multi-sig.service.ts @@ -92,23 +92,34 @@ export class MultiSigWalletService extends BaseContractService { const signer = await this.providerService.getSigner(); const contract = new ethers.Contract(contractAddress, abi, signer); - const deployedAddress = await this.calculateFutureAddress(contractAddress); - const tx = await contract.executeTransaction(index); + const input = dto.index + new Date().getTime().toString(); + const hashed = ethers.keccak256(ethers.toUtf8Bytes(input)); + const salt = BigInt(hashed.substring(0, 10)); - const txResponse: TransactionReceipt = await tx.wait(); - console.log('=>(multi-sig.service.ts:101) txResponse', txResponse.logs); - - const eventParse = parseLogs(txResponse, contract, 'ExecuteTransaction'); - const data = { - txHash: txResponse.hash, - sender: eventParse.args[0].toString(), - txIndex: eventParse.args[1].toString(), - }; if (isDeploy) { - return { ...data, deployedAddress }; + const tx = await contract.executeDeployTransaction(index, salt); + + const txResponse: TransactionReceipt = await tx.wait(); + const eventParse = parseLogs(txResponse, contract, 'ExecuteTransaction'); + const deployedParse = parseLogs(txResponse, contract, 'ContractDeployed'); + return { + txHash: txResponse.hash, + sender: eventParse.args[0].toString(), + txIndex: eventParse.args[1].toString(), + deployedAddress: deployedParse.args[0].toString(), + }; } else { - return data; + const tx = await contract.executeTransaction(index); + + const txResponse: TransactionReceipt = await tx.wait(); + + const eventParse = parseLogs(txResponse, contract, 'ExecuteTransaction'); + return { + txHash: txResponse.hash, + sender: eventParse.args[0].toString(), + txIndex: eventParse.args[1].toString(), + }; } } @@ -119,7 +130,7 @@ export class MultiSigWalletService extends BaseContractService { return getContractAddress({ from: contractAddress, - nonce: nonce + 1, + nonce: nonce, }); } diff --git a/chain-api/src/filters/http.filter.ts b/chain-api/src/filters/http.filter.ts index ce33efe..ee91b38 100644 --- a/chain-api/src/filters/http.filter.ts +++ b/chain-api/src/filters/http.filter.ts @@ -16,7 +16,6 @@ export class AllExceptionsFilter implements ExceptionFilter { console.log('🚀 ~ AllExceptionsFilter ~ exception:', exception); const ctx = host.switchToHttp(); const response = ctx.getResponse(); - const request = ctx.getRequest(); const httpStatus = exception instanceof HttpException ? exception.getStatus() diff --git a/chain-api/src/hardhat/contracts/License.sol b/chain-api/src/hardhat/contracts/License.sol index 82a94c4..1cff4ad 100644 --- a/chain-api/src/hardhat/contracts/License.sol +++ b/chain-api/src/hardhat/contracts/License.sol @@ -68,13 +68,13 @@ contract StreamingRightsManagement is ChainlinkClient, ConfirmedOwner { //update share //change payout address // - function getShare(address owner) public returns(uint){ + function getShare(address owner) public view returns(uint){ return ownerShare[owner]; } // Send a request to the Chainlink oracle - function request() public { + function request() external onlyOwner{ Chainlink.Request memory req = _buildOperatorRequest(jobId, this.fulfill.selector); diff --git a/chain-api/src/hardhat/contracts/MultiSigWallet.sol b/chain-api/src/hardhat/contracts/MultiSigWallet.sol index 036d2a1..52522ea 100644 --- a/chain-api/src/hardhat/contracts/MultiSigWallet.sol +++ b/chain-api/src/hardhat/contracts/MultiSigWallet.sol @@ -132,14 +132,6 @@ contract MultiSigWallet { if (success) { transaction.executed = true; emit ExecuteTransaction(msg.sender, _txIndex, transaction.to); - if (returnData.length > 0) { - address deployedContractAddress; - assembly { - deployedContractAddress := mload(add(returnData, 20)) - } - // You can emit an event with the address of the deployed contract - emit ContractDeployed(deployedContractAddress); - } removeTransaction(_txIndex); } else { // Get the revert reason and emit it @@ -156,6 +148,39 @@ contract MultiSigWallet { } } + function executeDeployTransaction(uint _txIndex, uint256 _salt) public onlyOwner txExists(_txIndex) notExecuted(_txIndex) { + Transaction storage transaction = transactions[_txIndex]; + require( + transaction.numConfirmations >= numConfirmationsRequired, + "cannot execute tx" + ); + + address deployedAddress; + + bytes memory bytecode = transaction.data; + + // Assembly to deploy contract using CREATE2 + assembly { + deployedAddress := + create2( + callvalue(), // wei sent with current call + // Actual code starts after skipping the first 32 bytes + add(bytecode, 0x20), + mload(bytecode), // Load the size of code contained in the first 32 bytes + _salt // Salt from function arguments + ) + + if iszero(extcodesize(deployedAddress)) { revert(0, 0) } + } + + require(deployedAddress != address(0), "Failed to deploy contract"); + transaction.executed = true; + emit ExecuteTransaction(msg.sender, _txIndex, deployedAddress); + emit ContractDeployed(deployedAddress); + removeTransaction(_txIndex); + } + + function revokeConfirmation( uint _txIndex ) public onlyOwner txExists(_txIndex) notExecuted(_txIndex) {