diff --git a/packages/fuel/out/release/fuel-abi.json b/packages/fuel/out/release/fuel-abi.json index cd35ca6..326d709 100644 --- a/packages/fuel/out/release/fuel-abi.json +++ b/packages/fuel/out/release/fuel-abi.json @@ -14,7 +14,7 @@ { "type": "enum std::option::Option", "concreteTypeId": "2b4a62e8055c70f8b1030ea7e332c3ba1288d018326932966c12e739e3b39747", - "metadataTypeId": 2, + "metadataTypeId": 3, "typeArguments": [ "86d8c6f7cae21a575a05f79ba638fb0dad5282a73d2f4ff843b273d20db407a9" ] @@ -30,42 +30,47 @@ { "type": "struct HTLC", "concreteTypeId": "86d8c6f7cae21a575a05f79ba638fb0dad5282a73d2f4ff843b273d20db407a9", - "metadataTypeId": 5 + "metadataTypeId": 6 }, { "type": "struct TokenCommitted", "concreteTypeId": "78acd35e37502d98e65a2ab559087dd216a287a7451d4f935b390221d298b700", - "metadataTypeId": 6 + "metadataTypeId": 7 }, { "type": "struct TokenLockAdded", "concreteTypeId": "ae438802fd396d1a9e35c5d90ac591a3b07fefce2c695bbe8b413c97a45580a0", - "metadataTypeId": 7 + "metadataTypeId": 8 }, { "type": "struct TokenLocked", "concreteTypeId": "40a5216fe49383a63f3bc1fc9ed173b15d65507cf0afb1bf60b45455cf3c8cc2", - "metadataTypeId": 8 + "metadataTypeId": 9 }, { "type": "struct TokenRedeemed", "concreteTypeId": "763c4ffa6ea9a443fa0bd80203751132ca64f37f23d2a7637091737e9cd5b7d7", - "metadataTypeId": 9 + "metadataTypeId": 10 }, { "type": "struct TokenRefuned", "concreteTypeId": "3305d3421a33ef2ee99d7b6a3d1e24e0f49eaee9476c84a9066d33eb7dc306d7", - "metadataTypeId": 10 + "metadataTypeId": 11 }, { "type": "struct std::address::Address", "concreteTypeId": "f597b637c3b0f588fb8d7086c6f4735caa3122b85f0423b82e489f9bb58e2308", - "metadataTypeId": 11 + "metadataTypeId": 12 + }, + { + "type": "struct std::b512::B512", + "concreteTypeId": "745e252e80bec590efc3999ae943f07ccea4d5b45b00bb6575499b64abdd3322", + "metadataTypeId": 14 }, { "type": "struct std::vec::Vec", "concreteTypeId": "742d7b76206a39cfad7eaec9b457390bbd0a92fe1da596db414daa0e4964bf82", - "metadataTypeId": 15, + "metadataTypeId": 17, "typeArguments": [ "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e" ] @@ -85,22 +90,32 @@ "metadataTypeId": 0 }, { - "type": "enum std::identity::Identity", + "type": "[_; 2]", "metadataTypeId": 1, + "components": [ + { + "name": "__array_element", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "enum std::identity::Identity", + "metadataTypeId": 2, "components": [ { "name": "Address", - "typeId": 11 + "typeId": 12 }, { "name": "ContractId", - "typeId": 13 + "typeId": 15 } ] }, { "type": "enum std::option::Option", - "metadataTypeId": 2, + "metadataTypeId": 3, "components": [ { "name": "None", @@ -108,24 +123,24 @@ }, { "name": "Some", - "typeId": 3 + "typeId": 4 } ], "typeParameters": [ - 3 + 4 ] }, { "type": "generic T", - "metadataTypeId": 3 + "metadataTypeId": 4 }, { "type": "raw untyped ptr", - "metadataTypeId": 4 + "metadataTypeId": 5 }, { "type": "struct HTLC", - "metadataTypeId": 5, + "metadataTypeId": 6, "components": [ { "name": "dstAddress", @@ -145,11 +160,11 @@ }, { "name": "sender", - "typeId": 11 + "typeId": 12 }, { "name": "srcReceiver", - "typeId": 11 + "typeId": 12 }, { "name": "hashlock", @@ -169,7 +184,7 @@ }, { "name": "assetId", - "typeId": 12 + "typeId": 13 }, { "name": "redeemed", @@ -183,7 +198,7 @@ }, { "type": "struct TokenCommitted", - "metadataTypeId": 6, + "metadataTypeId": 7, "components": [ { "name": "Id", @@ -203,11 +218,11 @@ }, { "name": "sender", - "typeId": 11 + "typeId": 12 }, { "name": "srcReceiver", - "typeId": 11 + "typeId": 12 }, { "name": "srcAsset", @@ -223,13 +238,13 @@ }, { "name": "assetId", - "typeId": 12 + "typeId": 13 } ] }, { "type": "struct TokenLockAdded", - "metadataTypeId": 7, + "metadataTypeId": 8, "components": [ { "name": "Id", @@ -247,7 +262,7 @@ }, { "type": "struct TokenLocked", - "metadataTypeId": 8, + "metadataTypeId": 9, "components": [ { "name": "Id", @@ -271,11 +286,11 @@ }, { "name": "sender", - "typeId": 11 + "typeId": 12 }, { "name": "srcReceiver", - "typeId": 11 + "typeId": 12 }, { "name": "srcAsset", @@ -291,13 +306,13 @@ }, { "name": "assetId", - "typeId": 12 + "typeId": 13 } ] }, { "type": "struct TokenRedeemed", - "metadataTypeId": 9, + "metadataTypeId": 10, "components": [ { "name": "Id", @@ -305,13 +320,13 @@ }, { "name": "redeemAddress", - "typeId": 1 + "typeId": 2 } ] }, { "type": "struct TokenRefuned", - "metadataTypeId": 10, + "metadataTypeId": 11, "components": [ { "name": "Id", @@ -321,7 +336,7 @@ }, { "type": "struct std::address::Address", - "metadataTypeId": 11, + "metadataTypeId": 12, "components": [ { "name": "bits", @@ -331,7 +346,7 @@ }, { "type": "struct std::asset_id::AssetId", - "metadataTypeId": 12, + "metadataTypeId": 13, "components": [ { "name": "bits", @@ -339,9 +354,19 @@ } ] }, + { + "type": "struct std::b512::B512", + "metadataTypeId": 14, + "components": [ + { + "name": "bits", + "typeId": 1 + } + ] + }, { "type": "struct std::contract_id::ContractId", - "metadataTypeId": 13, + "metadataTypeId": 15, "components": [ { "name": "bits", @@ -351,11 +376,11 @@ }, { "type": "struct std::vec::RawVec", - "metadataTypeId": 14, + "metadataTypeId": 16, "components": [ { "name": "ptr", - "typeId": 4 + "typeId": 5 }, { "name": "cap", @@ -363,20 +388,20 @@ } ], "typeParameters": [ - 3 + 4 ] }, { "type": "struct std::vec::Vec", - "metadataTypeId": 15, + "metadataTypeId": 17, "components": [ { "name": "buf", - "typeId": 14, + "typeId": 16, "typeArguments": [ { "name": "", - "typeId": 3 + "typeId": 4 } ] }, @@ -386,7 +411,7 @@ } ], "typeParameters": [ - 3 + 4 ] } ], @@ -418,6 +443,37 @@ } ] }, + { + "inputs": [ + { + "name": "signature", + "concreteTypeId": "745e252e80bec590efc3999ae943f07ccea4d5b45b00bb6575499b64abdd3322" + }, + { + "name": "Id", + "concreteTypeId": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e" + }, + { + "name": "hashlock", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "timelock", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "name": "add_lock_sig", + "output": "1b5759d94094368cfd443019e7ca5ec4074300e544e5ea993a979f5da627261e", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, { "inputs": [ { diff --git a/packages/fuel/out/release/fuel.bin b/packages/fuel/out/release/fuel.bin index 419751a..5add5f9 100644 Binary files a/packages/fuel/out/release/fuel.bin and b/packages/fuel/out/release/fuel.bin differ diff --git a/packages/fuel/scripts/addLock.ts b/packages/fuel/scripts/addLock.ts index ee2294e..cc8b84b 100644 --- a/packages/fuel/scripts/addLock.ts +++ b/packages/fuel/scripts/addLock.ts @@ -5,18 +5,19 @@ import * as path from 'path'; const filePath = path.join(__dirname, '../out/release/fuel-abi.json'); const contractAbi = JSON.parse(fs.readFileSync(filePath, 'utf-8')); -const contractAddressString = '0x33dab65c45258fea05215fca2a2578fb94b13920d5a736e02ac9aae517b2bd96'; +const contractAddressString = '0x00f3dfc843089523a41a08a611ad39eef57de6ebdb58915840ed81d3fe9a5476'; async function getWalletBalances() { const provider = await Provider.create('https://testnet.fuel.network/v1/graphql'); const mnemonic = 'energy knife treat involve affair tobacco school verb risk laugh exchange vendor'; + // const mnemonic = 'connect people age absurd suggest river trust lunch joke clerk clinic blind'; const wallet: WalletUnlocked = Wallet.fromMnemonic(mnemonic); wallet.connect(provider); const contractAddress = Address.fromB256(contractAddressString); const contractInstance = new Contract(contractAddress, contractAbi, wallet); - const Id = 1n; - const hashlock = "0xd4a671c0bb24f780c8ed7c13cfb6a554585bea038416afdcf806e73381db8417"; + const Id = 54079385413661825002756453772014361870896886140818619726462513491823303364787n; + const hashlock = "0x3b7674662e6569056cef73dab8b7809085a32beda0e8eb9e9b580cfc2af22a55"; const currentUnixTime = Math.floor(Date.now() / 1000) + 3600; const timelock = DateTime.fromUnixSeconds(currentUnixTime).toTai64(); diff --git a/packages/fuel/scripts/addLockSig.ts b/packages/fuel/scripts/addLockSig.ts new file mode 100644 index 0000000..42506b9 --- /dev/null +++ b/packages/fuel/scripts/addLockSig.ts @@ -0,0 +1,56 @@ +import { Contract, Wallet, Provider, Address, DateTime, WalletUnlocked, Signer, sha256, bn, hashMessage, keccak256, arrayify, hexlify, BytesLike } from 'fuels'; +import * as fs from 'fs'; +import * as path from 'path'; + +const filePath = path.join(__dirname, '../out/release/fuel-abi.json'); +const contractAbi = JSON.parse(fs.readFileSync(filePath, 'utf-8')); + +const contractAddressString = '0x00f3dfc843089523a41a08a611ad39eef57de6ebdb58915840ed81d3fe9a5476'; + +async function getWalletBalances() { + const provider = await Provider.create('https://testnet.fuel.network/v1/graphql'); + const signerMnemonic = 'energy knife treat involve affair tobacco school verb risk laugh exchange vendor'; + const signerWallet: WalletUnlocked = Wallet.fromMnemonic(signerMnemonic); + signerWallet.connect(provider); + + const senderMnemonic = 'connect people age absurd suggest river trust lunch joke clerk clinic blind'; + const senderWallet: WalletUnlocked = Wallet.fromMnemonic(senderMnemonic); + senderWallet.connect(provider); + + const contractAddress = Address.fromB256(contractAddressString); + const contractInstance = new Contract(contractAddress, contractAbi, senderWallet); + const Id = 54079385413661825002756453772014361870896886140818619726462513491823303364788n; + const hashlock = "0x3b7674662e6569056cef73dab8b7809085a32beda0e8eb9e9b580cfc2af22a55"; + const currentUnixTime = Math.floor(Date.now() / 1000) + 3600; + const timelock = DateTime.fromUnixSeconds(currentUnixTime).toTai64(); + + const IdHex = '0x' + Id.toString(16).padStart(64, '0'); + const timelockHex = '0x' + BigInt(timelock).toString(16).padStart(64, '0'); + + const msg = [IdHex,hashlock,timelockHex]; + + const msgBytes = Uint8Array.from( + msg.flatMap(hexStr => Array.from(arrayify(hexStr))) +); + let signedmessage = signerWallet.signer().sign(sha256(msgBytes)) + const signature = hexlify(signedmessage) + console.log('signiature verifeid off chain: ',signerWallet.address.toB256() == Signer.recoverAddress(sha256(msgBytes),signature).toB256()); + + try { + const { transactionId, waitForResult } = await contractInstance.functions + .add_lock_sig(signature,IdHex,hashlock,timelock) + .call(); + + const { logs,value } = await waitForResult(); + + console.log('tx id: ', transactionId); + console.log('add_lock function logs: ',logs[0]); + console.log('add_lock function result:', value); + } catch (error) { + console.error('Error calling add_lock function:', error); + } +} + +getWalletBalances().catch(console.error); + + diff --git a/packages/fuel/scripts/commit.ts b/packages/fuel/scripts/commit.ts index 2002a8c..ea92e3c 100644 --- a/packages/fuel/scripts/commit.ts +++ b/packages/fuel/scripts/commit.ts @@ -5,7 +5,7 @@ import * as path from 'path'; const filePath = path.join(__dirname, '../out/release/fuel-abi.json'); const contractAbi = JSON.parse(fs.readFileSync(filePath, 'utf-8')); -const contractAddressString = '0x33dab65c45258fea05215fca2a2578fb94b13920d5a736e02ac9aae517b2bd96'; +const contractAddressString = '0x00f3dfc843089523a41a08a611ad39eef57de6ebdb58915840ed81d3fe9a5476'; async function getWalletBalances() { const provider = await Provider.create('https://testnet.fuel.network/v1/graphql'); @@ -20,7 +20,7 @@ async function getWalletBalances() { const dstAddress = "0QAS8JNB0G4zVkdxABCLVG-Vy3KXE3W3zz1yxpnfu4J-B40y".padEnd(64, ' '); const srcAsset = "ETH".padEnd(64, ' '); const srcReceiver = {"bits":"0x6364b23e8c34d46d0b68d20e0c1463230a9243a1dd710a7dd8b32dfb927af53a"}; - const currentUnixTime = Math.floor(Date.now() / 1000) + 3600; + const currentUnixTime = Math.floor(Date.now() / 1000) + 10; const timelock = DateTime.fromUnixSeconds(currentUnixTime).toTai64(); const contractAddress = Address.fromB256(contractAddressString); diff --git a/packages/fuel/scripts/getContracts.ts b/packages/fuel/scripts/getContracts.ts index 159b04b..8da0f0b 100644 --- a/packages/fuel/scripts/getContracts.ts +++ b/packages/fuel/scripts/getContracts.ts @@ -5,7 +5,7 @@ import * as path from 'path'; const filePath = path.join(__dirname, '../out/release/fuel-abi.json'); const contractAbi = JSON.parse(fs.readFileSync(filePath, 'utf-8')); -const contractAddressString = '0xed0b3a20a5a0f6e0f6fec1a9f27630fde03fba04cb304c575543946eaf3d8756'; +const contractAddressString = '0x00f3dfc843089523a41a08a611ad39eef57de6ebdb58915840ed81d3fe9a5476'; async function getWalletBalances() { const provider = await Provider.create('https://testnet.fuel.network/v1/graphql'); diff --git a/packages/fuel/scripts/getDetails.ts b/packages/fuel/scripts/getDetails.ts index 9834191..3c8a551 100644 --- a/packages/fuel/scripts/getDetails.ts +++ b/packages/fuel/scripts/getDetails.ts @@ -5,7 +5,7 @@ import * as path from 'path'; const filePath = path.join(__dirname, '../out/release/fuel-abi.json'); const contractAbi = JSON.parse(fs.readFileSync(filePath, 'utf-8')); -const contractAddressString = '0x33dab65c45258fea05215fca2a2578fb94b13920d5a736e02ac9aae517b2bd96'; +const contractAddressString = '0x00f3dfc843089523a41a08a611ad39eef57de6ebdb58915840ed81d3fe9a5476'; async function getWalletBalances() { const provider = await Provider.create('https://testnet.fuel.network/v1/graphql'); @@ -18,7 +18,7 @@ async function getWalletBalances() { try { const { transactionId, waitForResult } = await contractInstance.functions - .get_details(100n) + .get_details(101n) .call(); const { value } = await waitForResult(); diff --git a/packages/fuel/scripts/init.ts b/packages/fuel/scripts/init.ts index 07b2951..0908eed 100644 --- a/packages/fuel/scripts/init.ts +++ b/packages/fuel/scripts/init.ts @@ -5,7 +5,7 @@ import * as path from 'path'; const filePath = path.join(__dirname, '../out/release/fuel-abi.json'); const contractAbi = JSON.parse(fs.readFileSync(filePath, 'utf-8')); -const contractAddressString = '0x33dab65c45258fea05215fca2a2578fb94b13920d5a736e02ac9aae517b2bd96'; +const contractAddressString = '0x00f3dfc843089523a41a08a611ad39eef57de6ebdb58915840ed81d3fe9a5476'; async function getWalletBalances() { const provider = await Provider.create('https://testnet.fuel.network/v1/graphql'); diff --git a/packages/fuel/scripts/lock.ts b/packages/fuel/scripts/lock.ts index c81377f..c6ab269 100644 --- a/packages/fuel/scripts/lock.ts +++ b/packages/fuel/scripts/lock.ts @@ -5,7 +5,7 @@ import * as path from 'path'; const filePath = path.join(__dirname, '../out/release/fuel-abi.json'); const contractAbi = JSON.parse(fs.readFileSync(filePath, 'utf-8')); -const contractAddressString = '0x33dab65c45258fea05215fca2a2578fb94b13920d5a736e02ac9aae517b2bd96'; +const contractAddressString = '0x00f3dfc843089523a41a08a611ad39eef57de6ebdb58915840ed81d3fe9a5476'; async function getWalletBalances() { const provider = await Provider.create('https://testnet.fuel.network/v1/graphql'); @@ -15,15 +15,15 @@ async function getWalletBalances() { // NOTE: All string variables should be padded to ensure they have 64 characters, // as the contract accepts only the str[64] type for string inputs. - const Id = 100n; + const Id = 101n; const dstChain = "TON".padEnd(64, ' '); const dstAsset = "Toncoin".padEnd(64, ' '); const dstAddress = "0QAS8JNB0G4zVkdxABCLVG-Vy3KXE3W3zz1yxpnfu4J-B40y".padEnd(64, ' '); const srcAsset = "ETH".padEnd(64, ' '); const srcReceiver = {"bits":"0x6364b23e8c34d46d0b68d20e0c1463230a9243a1dd710a7dd8b32dfb927af53a"}; - const currentUnixTime = Math.floor(Date.now() / 1000) + 100; + const currentUnixTime = Math.floor(Date.now() / 1000) + 10; const timelock = DateTime.fromUnixSeconds(currentUnixTime).toTai64(); - const hashlock = "0xd4a671c0bb24f780c8ed7c13cfb6a554585bea038416afdcf806e73381db8417"; + const hashlock = "0x3b7674662e6569056cef73dab8b7809085a32beda0e8eb9e9b580cfc2af22a55"; const contractAddress = Address.fromB256(contractAddressString); const contractInstance = new Contract(contractAddress, contractAbi, wallet); diff --git a/packages/fuel/scripts/redeem.ts b/packages/fuel/scripts/redeem.ts index 872d200..dc3ae49 100644 --- a/packages/fuel/scripts/redeem.ts +++ b/packages/fuel/scripts/redeem.ts @@ -5,7 +5,7 @@ import * as path from 'path'; const filePath = path.join(__dirname, '../out/release/fuel-abi.json'); const contractAbi = JSON.parse(fs.readFileSync(filePath, 'utf-8')); -const contractAddressString = '0x33dab65c45258fea05215fca2a2578fb94b13920d5a736e02ac9aae517b2bd96'; +const contractAddressString = '0x00f3dfc843089523a41a08a611ad39eef57de6ebdb58915840ed81d3fe9a5476'; async function getWalletBalances() { const provider = await Provider.create('https://testnet.fuel.network/v1/graphql'); @@ -15,8 +15,8 @@ async function getWalletBalances() { const contractAddress = Address.fromB256(contractAddressString); const contractInstance = new Contract(contractAddress, contractAbi, wallet); - const Id = 1n; - const secret = 9065364567159659789812097500307188665539569649970302555505078182575840194842n; + const Id = 101n; + const secret = 33648946896879551350753991616036334622602839139780100591470253765180571691018n; try { const { transactionId, waitForResult } = await contractInstance.functions diff --git a/packages/fuel/scripts/refund.ts b/packages/fuel/scripts/refund.ts index 489795d..37ca59b 100644 --- a/packages/fuel/scripts/refund.ts +++ b/packages/fuel/scripts/refund.ts @@ -5,7 +5,7 @@ import * as path from 'path'; const filePath = path.join(__dirname, '../out/release/fuel-abi.json'); const contractAbi = JSON.parse(fs.readFileSync(filePath, 'utf-8')); -const contractAddressString = '0x33dab65c45258fea05215fca2a2578fb94b13920d5a736e02ac9aae517b2bd96'; +const contractAddressString = '0x00f3dfc843089523a41a08a611ad39eef57de6ebdb58915840ed81d3fe9a5476'; async function getWalletBalances() { const provider = await Provider.create('https://testnet.fuel.network/v1/graphql'); diff --git a/packages/fuel/src/main.sw b/packages/fuel/src/main.sw index d04a279..52b75d2 100644 --- a/packages/fuel/src/main.sw +++ b/packages/fuel/src/main.sw @@ -9,6 +9,9 @@ use std::{ call_frames::*, hash::*, storage::storage_vec::*, + b512::B512, + ecr::ec_recover_address, + bytes_conversions::{u64::*, u256::*, b256::*}, }; abi LayerswapV8 { @@ -27,6 +30,9 @@ abi LayerswapV8 { #[storage(read,write)] fn add_lock(Id: u256, hashlock: b256, timelock: u64) -> u256; + #[storage(read,write)] + fn add_lock_sig(signature: B512,Id: u256, hashlock: b256, timelock: u64) -> u256; + #[payable] #[storage(read,write)] fn lock(Id: u256, @@ -117,8 +123,24 @@ fn has_htlc(Id: u256) -> bool { } } +#[storage(read,write)] +fn apply_lock(Id: u256, hashlock: b256, timelock: u64) -> u256 { + let mut htlc: HTLC = storage.contracts.get(Id).try_read().unwrap(); + require(!htlc.refunded,"Already Refunded"); + require(timelock > timestamp(),"Not Future Timelock"); + require(htlc.hashlock == b256::from(0),"Hashlock Already Set"); + htlc.hashlock = hashlock; + htlc.timelock = timelock; + storage.contracts.insert(Id, htlc); + + log(TokenLockAdded {Id: Id, + hashlock: hashlock, + timelock: timelock + }); + Id +} + impl LayerswapV8 for Contract { - // TODO: reasearch for better approach #[storage(read,write)] fn initialize(salt: u256) -> bool{ let num: u256 = storage.contractSeed.read(); @@ -204,8 +226,6 @@ impl LayerswapV8 for Contract { fn add_lock(Id: u256, hashlock: b256, timelock: u64) -> u256 { require(has_htlc(Id), "HTLC Does Not Exist"); let mut htlc: HTLC = storage.contracts.get(Id).try_read().unwrap(); - require(!htlc.refunded,"Already Refunded"); - require(timelock > timestamp(),"Not Future Timelock"); let sender = match msg_sender().unwrap() { Identity::Address(addr) => addr, _ => {require(false, "No Allowance"); @@ -214,16 +234,19 @@ impl LayerswapV8 for Contract { Address::from(0x0000000000000000000000000000000000000000000000000000000000000000) }, }; require(htlc.sender == sender, "No Allowance"); - require(htlc.hashlock == b256::from(0),"Hashlock Already Set"); - htlc.hashlock = hashlock; - htlc.timelock = timelock; - storage.contracts.insert(Id, htlc); + apply_lock(Id,hashlock,timelock) + } - log(TokenLockAdded {Id: Id, - hashlock: hashlock, - timelock: timelock - }); - Id + #[storage(read,write)] + fn add_lock_sig(signature: B512,Id: u256, hashlock: b256, timelock: u64) -> u256{ + require(has_htlc(Id), "HTLC Does Not Exist"); + let mut htlc: HTLC = storage.contracts.get(Id).try_read().unwrap(); + let IdBytes: b256 = Id.into(); + let timelockBytes: b256 = timelock.as_u256().into(); + let message: [b256;3] = [IdBytes,hashlock,timelockBytes]; + let messageHash = sha256(message); + require(htlc.sender == ec_recover_address(signature,messageHash).unwrap(),"Invalid Signature"); + apply_lock(Id,hashlock,timelock) } #[payable]