[TIL] 2023-07-10 DAY74
GIT 주소
https://github.com/dowoo303/SOLIDITY
https://github.com/dowoo303/hardhat
오늘 배운것들
- delegatecall과 call의 차이
- interface abstract, library
- npm에 배포하는법
각종 팁
회고
다른 컨트랙트의 함수를 빌려서 자신 내 컨트랙트의 상태를 변경시킴(이 경우 다른 컨트랙트의 함수를 실행시킨다고 해서 그 컨트랙트의 값을 변경시키지는 않음)
-> 즉, 남이 만들어놓은 함수를 내 컨트랙트로 가져와서 사용하는 것과 같다.
사용조건 : 스토리지 슬롯이 동일해야함(갯수가 완전 동일하지는 않아도 되지만 순서는 완벽히 같아야한다)
서로 통신 : fallback
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
// delegatecall과 call의 차이
// 스토리지 슬롯에 동일하게 작성되어야한다
contract A {
uint public num;
address public sender;
function setNum(uint _num) public {
num = _num;
sender = msg.sender;
}
function add(uint _a, uint _b) public {
// num = _a+_b;
// sender = msg.sender;
addUpgrade(_a, _b);
}
function addUpgrade(uint _a, uint _b) public {
num = _a+_a+_b;
sender = msg.sender;
}
}
// A의 함수를 이용해서 B의 상태변수 변경
contract B {
uint public num;
address public sender;
function setNum(address _contract, uint _a, uint _b) public {
(bool success, bytes memory data) = _contract.delegatecall(abi.encodeWithSignature("add(uint256,uint256)",_a,_b));
require(success, "did not work");
}
address iAmWatching;
function watching(address _contract) public {
iAmWatching = _contract;
}
function setNumber(uint _a, uint _b) public {
(bool success, bytes memory data) = iAmWatching.delegatecall(abi.encodeWithSignature("add(uint256,uint256)", _a, _b));
require(success, "did not work");
}
}
contract B2 {
uint public num;
address public sender;
address iAmWatching;
string public str;
function setNum(address _contract, uint _a, uint _b) public {
(bool success, bytes memory data) = _contract.delegatecall(abi.encodeWithSignature("add(uint256,uint256)",_a,_b));
require(success, "did not work");
}
function watching(address _contract) public {
iAmWatching = _contract;
}
function setNumber(uint _a, uint _b) public {
(bool success, bytes memory data) = iAmWatching.delegatecall(abi.encodeWithSignature("add(uint256,uint256)", _a, _b));
require(success, "did not work");
}
}
// B와 다르게 C의 상태변수가 변한 것이 아니라 A의 상태변수만 변경
contract C {
uint public num;
address public sender;
function setNum(address _contract, uint _num) public {
(bool success, bytes memory data) = _contract.call(abi.encodeWithSignature("setNum(uint256)", _num));
require(success, "did not work");
}
}
사용이유: 필수적인 코드들을 알려주는 역할(기초공사에 반드시 필요한 함수 모음) -> 코드를 빠르게 재활용 가능
타컨트랙트형(주소) 대신 interface(주소)로 이용
관리 효율 증가 및 가스비 효율 개선
interface : 껍데기
abstract : 껍데기+약간의 변화
(interface에서 특정 함수는 다른식으로 구성하고 싶을때)
library : 갖다 쓰기
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
interface ICalculator {
function count() external view returns(uint); // 상태변수
function increment() external;
function decrement() external;
function mul() external;
}
contract myContract {
function increment(address _Calculator) public {
ICalculator(_Calculator).increment();
}
function decrement(address _Calculator) public {
ICalculator(_Calculator).decrement();
}
function count(address _Calculator) public view returns(uint) {
return ICalculator(_Calculator).count();
}
}
npm login으로 로그인npm publish 명령어로 배포(만약 npm에 같은 이름이 있을경우 package.json에서 이름변경해주기)npm i 이름 으로 복사 가능