Gelato๐ฆ๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋งํธ ๊ณ์ฝ ์คํ์ ์๋ํํ๋ ๋ฐฉ๋ฒ
10856 ๋จ์ด defiblockchainautomationtooling
๊ทธ๋์ ์ฌ๊ธฐ์ ํด๊ฒฐ์ฑ ์ด ์์ต๋๋ค โ ์คํจ์ ์ค์ฌ์ ์ด ๋๊ธฐ ์ฌ์ด ๊ธฐ๋ณธ ์ธํ๋ผ๋ฅผ ์คํํ ํ์ ์์ด ๋ฉ์ง ์ค๋งํธ ๊ณ์ฝ์ ๊ตฌ์ถํ๋ ๋ฐ ๊ณ์ ์ง์คํ์ญ์์ค. Gelato์ด(๊ฐ) ๋น์ ์ ์ํด ์ผํ๊ฒ ํ์ญ์์ค.
๐โโ๏ธ ์ถ๋ฐ
์ด๋ฏธ ์ค๋งํธ ๊ณ์ฝ์ ๋ฐฐํฌํ๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ Gelato๊ฐ ํน์ ์๊ฐ์ ์ค๋งํธ ๊ณ์ฝ์ ํธ์ถํ๊ธฐ๋ฅผ ์ํฉ๋๋ค. Gelato์๊ฒ ์๋ ค์ค ๋ฆฌ์กธ๋ฒ ์ปจํธ๋ํธ๋ฅผ ๋ฐฐํฌํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
"์ด๋ด ์ด ๊ธฐ๋ฅ์ ๋งค์๊ฐ ์ฌ๊ธฐ๋ก ๋ถ๋ฌ์ค"
๋ค์์ Gelato์์ ํธ์ถํ๋ ค๋ ํจ์buy()
์ ์์
๋๋ค. ์ด ๊ธฐ๋ฅ์ Uniswap V2๋ฅผ ํตํด ETH๋ฅผ ๊ตฌ๋งคํฉ๋๋ค.
uint256 public lastBought;
function buy(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external {
require(block.timestamp >= lastBought + 1 hours);
IERC20(path[0]).approve(address(router), amountIn);
router.swapExactTokensForETH(
amountIn,
amountOutMin,
path,
to,
deadline
);
lastBought = block.timestamp;
}
๋ค์์ ํ์ธ์ ๊ณ์ฝ์ ์์
๋๋ค. checker()
๋ lastBought
๊ฐ ํ ์๊ฐ ์ด์ ์ง๋ ๊ฒฝ์ฐ true๋ฅผ ๋ฐํํฉ๋๋ค. ๊ทธ๋ฌ๋ฉด Gelato๊ฐ ์์์ ์ธ๊ธํ buy()
ํจ์๋ฅผ ํธ์ถํ๋ผ๋ ๋ฉ์์ง๊ฐ ํ์๋ฉ๋๋ค.
contract Resolver {
address public immutable owner;
ISwap public immutable swap;
address WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
constructor(address _swap) public {
owner = msg.sender;
swap = ISwap(_swap);
}
function checker()
external
view
returns (bool canExec, bytes memory execPayload)
{
address[] memory path = new address[](2);
path[0] = USDT;
path[1] = WETH;
uint256 deadline = block.timestamp + 10 minutes;
uint256 lastBought = swap.lastBought();
if (lastBought >= 1 hours) {
bytes4 selector =
bytes4(keccak256(
"buy(uint256,uint256,address[],address,uint256"));
execPayload = abi.encodeWithSelector(
selector,
1000 ether,
0,
path,
owner,
deadline
);
canExec = true;
return (canExec, execPayload);
}
}
}
Gelato๋ ๋ชจ๋ ๋ธ๋ก์์ ์ด๋ฅผ ์คํ์ฒด์ธchecker()
์ด๋ผ๊ณ ๋ถ๋ฆ
๋๋ค. canExec
๊ฐ true๋ฅผ ๋ฐํํ๋ฉด ์งํ์๋ execPayload
์ ํจ๊ป ํธ๋์ญ์
์ ๋ณด๋
๋๋ค.
ํ์ธ์ ๊ณ์ฝ ์์ฑ ๋ฐฉ๋ฒ์ ๋ํ ์์ธํ ๋ด์ฉ์ docs์ ์ฐธ์กฐํ์ญ์์ค.
๐ทโโ๏ธ ์์
๋ง๋ค๊ธฐ
ํ์ธ์ ๊ณ์ฝ์ ๋ฐฐํฌํ๋ฉด ์ด๋ฏธ ์ ๋ฐ์ ์๋ฃ๋ ๊ฒ์
๋๋ค. ์ด์ ์์
์ ์ ์ถํด์ผ ํฉ๋๋ค. Gelato๋ PokeMe UI๋ก ์์
์ ์ถ์ ๋งค์ฐ ์ฝ๊ฒ ๋ง๋ญ๋๋ค.
1. ํฌ์ผ๋ชฌ์คํฐ ํํ์ด์ง ๋ฐฉ๋ฌธ
์ฌ๊ธฐ์์ ํ์ฌ ์์
๊ณผ ์์ก์ ๋ณผ ์ ์์ต๋๋ค.
2. ์์
์ ์ถ์ ํด๋ฆญํฉ๋๋ค.
์ฌ๊ธฐ์ ์๋์ผ๋ก ์ฑ์์ผ ํ๋ ๋ ๊ฐ์ ํ๋๊ฐ ์์ต๋๋ค.
uint256 public lastBought;
function buy(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external {
require(block.timestamp >= lastBought + 1 hours);
IERC20(path[0]).approve(address(router), amountIn);
router.swapExactTokensForETH(
amountIn,
amountOutMin,
path,
to,
deadline
);
lastBought = block.timestamp;
}
contract Resolver {
address public immutable owner;
ISwap public immutable swap;
address WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
constructor(address _swap) public {
owner = msg.sender;
swap = ISwap(_swap);
}
function checker()
external
view
returns (bool canExec, bytes memory execPayload)
{
address[] memory path = new address[](2);
path[0] = USDT;
path[1] = WETH;
uint256 deadline = block.timestamp + 10 minutes;
uint256 lastBought = swap.lastBought();
if (lastBought >= 1 hours) {
bytes4 selector =
bytes4(keccak256(
"buy(uint256,uint256,address[],address,uint256"));
execPayload = abi.encodeWithSelector(
selector,
1000 ether,
0,
path,
owner,
deadline
);
canExec = true;
return (canExec, execPayload);
}
}
}
ํ์ธ์ ๊ณ์ฝ์ ๋ฐฐํฌํ๋ฉด ์ด๋ฏธ ์ ๋ฐ์ ์๋ฃ๋ ๊ฒ์ ๋๋ค. ์ด์ ์์ ์ ์ ์ถํด์ผ ํฉ๋๋ค. Gelato๋ PokeMe UI๋ก ์์ ์ ์ถ์ ๋งค์ฐ ์ฝ๊ฒ ๋ง๋ญ๋๋ค.
1. ํฌ์ผ๋ชฌ์คํฐ ํํ์ด์ง ๋ฐฉ๋ฌธ
์ฌ๊ธฐ์์ ํ์ฌ ์์ ๊ณผ ์์ก์ ๋ณผ ์ ์์ต๋๋ค.
2. ์์ ์ ์ถ์ ํด๋ฆญํฉ๋๋ค.
์ฌ๊ธฐ์ ์๋์ผ๋ก ์ฑ์์ผ ํ๋ ๋ ๊ฐ์ ํ๋๊ฐ ์์ต๋๋ค.
์คํ ์ฃผ์๋ฅผ ์ ๋ ฅํ๋ฉด ์ ํํ ์ ์๋ ํจ์ ๋ชฉ๋ก์ด ๋ํ๋ฉ๋๋ค.
3. Gelato๊ฐ ํธ์ถํ ๊ธฐ๋ฅ์ ์ ํํฉ๋๋ค.
Etherscan/Polygonscan์์ ๊ณ์ฝ์ ํ์ธํ๋์ง ํ์ธํ์ญ์์ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ํ์ธํด์ผ ํฉ๋๋คmanually.
๋ฆฌ์กธ๋ฒ ์ฃผ์์๋ ๋์ผํ๊ฒ ์ ์ฉ๋ฉ๋๋ค.
dashboard ์์ ์ ์ถํ ๋ชจ๋ ์์ ์ ๋ณผ ์ ์์ต๋๋ค.
์์ ์ ํด๋ฆญํ๋ฉด ์์ธํ ๋ด์ฉ๊ณผ ์์ ์ ๋ชจ๋ ์ด์ ์คํ์ ๋ณผ ์ ์์ต๋๋ค.
๐ค ์๊ธ ์๊ธ
์์
์ ์ ์ถํ ํ ๋ง์ง๋ง ๋จ๊ณ๋ ํธ๋์ญ์
์คํ์ ๋ํด ์งํ์์๊ฒ ์ง๋ถํ๋ ๋ฐ ์ฌ์ฉํ ์ผ๋ถ ์๊ธ์ ์์นํ๋ ๊ฒ์
๋๋ค.
์ค๋งํธ ๊ณ์ฝ์ ๋คํธ์ํฌ์ ๋ฐ๋ผ ์ผ๋ถ ETH ๋๋ MATIC์ ์์นํ์ญ์์ค.
๊ทธ๋ฌ๋ฉด ์์ก์ด ๋์๋ณด๋์ ๋ํ๋ฉ๋๋ค.
๐ ๋ชจ๋ ์๋ฃ
์ค๋น๊ฐ ์๋ฃ๋์์ต๋๋ค! Gelato๋ ์ด์ ์ค๋งํธ ๊ณ์ฝ์ ๋ชจ๋ํฐ๋งํ๊ณ ์ง์ ๋ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋๋ฉด ์คํํฉ๋๋ค!
Gelato PokeMe๋ Ethereum ๋ฉ์ธ๋ท, Ropsten ๋ฐ Polygon์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ค์์ contract addresses์
๋๋ค!
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(Gelato๐ฆ๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋งํธ ๊ณ์ฝ ์คํ์ ์๋ํํ๋ ๋ฐฉ๋ฒ), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค
https://dev.to/gelato/how-to-automate-your-smart-contract-executions-1d14
ํ
์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ
์ธ ๋ฐ๊ฒฌ์ ์ ๋
(Collection and Share based on the CC Protocol.)
์ค๋น๊ฐ ์๋ฃ๋์์ต๋๋ค! Gelato๋ ์ด์ ์ค๋งํธ ๊ณ์ฝ์ ๋ชจ๋ํฐ๋งํ๊ณ ์ง์ ๋ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋๋ฉด ์คํํฉ๋๋ค!
Gelato PokeMe๋ Ethereum ๋ฉ์ธ๋ท, Ropsten ๋ฐ Polygon์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ค์์ contract addresses์ ๋๋ค!
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(Gelato๐ฆ๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋งํธ ๊ณ์ฝ ์คํ์ ์๋ํํ๋ ๋ฐฉ๋ฒ), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://dev.to/gelato/how-to-automate-your-smart-contract-executions-1d14ํ ์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค