지능 계약 모호화
어떻게 두더지 가장자리의 병례를 발견합니까
어, 어이구!
지능 계약을 작성하는 것은 겁이 많은 사람에게 적합하지 않다.
최근에 나는 Yield Protocol의 오프라인에 참여했다.들어보지 못한 사람들에게는 이더리움의 고정금리 대출 플랫폼이다.지능 계약의 가장자리에 있는 수학 공식도 실현했다.
Yield Protocol도 배포 즉시 잊어버리는 플랫폼이다.일단 우리가 상장되면 우리는 사용자와 우리의 소프트웨어의 상호작용을 막을 수 없고 핵심 계약의 어떠한 빈틈도 복구할 수 없다.
We could go up like a rocket, and then explode.
그러나 우리는 없다. 우리는 놀라운 작은 실수가 하나 있는데, 그 중 핵심 스마트 계약은 하나도 없다.
원인 중 하나는 모호기를 사용하여 단원이나 집적 테스트로 찾을 수 없는 가장자리를 찾는 것이다.모호기를 사용하는 것은 아직 흔한 일이 아니다. 많은 사람들이 나에게 이 글을 쓰고 그들의 계약을 모호하게 하는 것을 도와달라고 요구한다.도착했습니다.
모호함은 무엇입니까?
fuzzing에 이르러 나는 의외의 결과가 발생하는 값을 찾아내기 위해 대량이나 무작위 장면을 테스트하는 것을 알게 되었다.
https://medium.com/media/1eaeb580ff20ffea52133c4016eedb46/href
예를 들어 수익률에서 우리는 분수지수를 계산하는데 분수지수는 교체하여 계산한 것이기 때문에 이더리움에서 운행하는 것은 매우 비싸다. 왜냐하면 이더리움에서 모든 조작에 돈을 써야 하기 때문이다.
사용자에게 돈을 절약하기 위해 우리는 수익률로 해커를 공격했다exponential calculation algorithm to stop calculating decimals after a while.불리한 점은 우리의 스마트 계약의 현재 거래 가격이 수학적 이상적인 무작위 수량에서 벗어난다는 것이다.
그런데 얼마나 멀어졌어요?우리는 그것을 가격을 이상적인 가격의 1센트 이내로 유지할 수 있습니까?
유일하게 아는 방법은 대량의 랜덤 장면으로 스마트 계약을 테스트하는 것이다.Trail of Bits 코드 감사 기간에 모호기를 사용하는 것이 우리가 어떻게 이 점을 할 수 있는지 알려준다.
어떻게 모호한가
우선, 너는 반드시 install echidna 해야 한다.웹 사이트의 옵션에서 나는 Ubuntu의 미리 컴파일된 바이너리 파일을 다운로드하는 데 성공했다.이를 위해서는 cryptic-compile 및 slither 을 설치해야 합니다.나는 내가 몇 번의 노력을 들여서야 그것을 완성한 것을 기억한다. 이것은 최근에 보기 드문 일이다. 모든 물건이 npm 가방에 있다.
Fuzzing is not easy, the tools are rough, and the math is hard, but it is worth it.
만약 당신이 도움을 필요로 한다면, 당신은 채널에 가입해야 합니다.
Empire Hacking Slack 많은 문서와 강좌가 있어서 나는 전혀 이해할 수 없다.내 목숨을 구해준 것은 구스타보 그리코(Gustavo Grieco)의 운행 예시였다. 그 이후로 나는 그것을 조정하고 다시 사용했다.아마도 언젠가는 나는 더욱 정교한 세부 사항을 배울 것이다.
간단히 말하면, 당신은 설정이 필요합니다.yaml 파일, 이것은 나의 것이다.
seqLen: 50
testLimit: 20000
prefix: “crytic_”
deployer: “0x41414141”
sender: [“0x42424242”, “0x43434343”]
cryticArgs: [“ — compile-force-framework”, “Buidler”]
coverage: true
checkAsserts: true
너의 이 일에 대한 추측은 나와 마찬가지로 좋다.RTFM.아니요.그리고 테스트할 불변량으로 견고한 계약을 작성합니다. 이 계약 테스트echidna github의muld 함수입니다.
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.6.10;
import "../helpers/DecimalMath.sol";
/// [@dev](http://twitter.com/dev) Implements simple fixed point math mul and div operations for 27 decimals.
contract DecimalMathInvariant is DecimalMath {
function muld_(uint256 x, uint256 y)
public pure returns (uint256)
{
uint z = muld(x, y);
assert((x * y) / UNIT == z); // Assert math
assert (divd(z, y) <= x); // We are rounding down
// Assert revert on overflow
if(y > UNIT) assert(z >= x); // x could be zero
if(y < UNIT) assert(z <= x); // y could be zero
}
}
우리는 본 계약의 DecimalMath.sol 함수를 20000회 호출할 것이다.바늘두더지는 공공이기 때문에 이 함수를 실행해야 한다는 것을 안다.이 함수는 두 개의 매개 변수 (x와 y) 가 있기 때문에 바늘두더지는 실행할 때마다 이 매개 변수에 무작위 값을 사용합니다.바늘두더지가 운행할 때, 그것은 필요로 인해 회복은 성공적이라고 생각했지만, 단언으로 인해 회복은 실패했다.
위의 계약에서 나는 부동점 곱셈의 네 가지 속성을 검사했다.
DecimalMath.muld
검사 https://medium.com/media/813a305cc73b77793ac5a7f774f52159/href 를 통해 테스트 중인 모든 변수를 확인할 수 있습니다.침두더지는 계약 중의 모든 공공 기능을 이행할 것이다.
현재 당신은 이미 테스트를 준비:
$ echidna-test . — contract DecimalMathInvariant — config contracts/invariants/config.yaml
이 두 파라미터는 the full contract입니다. 우리는 그 중에서 불변량을 인코딩했습니다. (우리가 테스트 중인 목표 계약도 경로도 아닙니다.)두 번째 매개 변수는 이전name of the contract이다.침두더지는 계약을 분석하고 계약을 맺는 데 시간이 좀 걸릴 것이다. 결국은 다음과 같다.
path to the .yaml file 영광
더 좋음
너는 안에 이상한 것이 있다는 것을 알아차릴 수 있을 것이다.우리가 모호하게 하고 있는 이 단원은 무엇입니까?
불변량 열기 및 닫기
현재, 파일에서 틀림없이 이렇게 하는 방법이 있을 것이다. 그러나 나는 함수의 가시성을 사용하여 변수를 열고 닫는다.
침두더지는 당신의 계약 중의 모든 공공 기능에 대해 모호하게 처리할 것이다.그건 니가 원하는 게 아닐 수도 있어.때때로, 당신은 계약 중의 10배가 아니라 문제를 일으키는 함수를 테스트하고 싶을 수도 있고, 그 중 9배가 통과할 수도 있습니다.때때로 모호하고 싶지 않은 조수 함수가 있을 수도 있습니다.
이 경우, 함수를 내부 함수로 성명하기만 하면 바늘두더지는 무시합니다.모든 상태 변수도 내부 변수로 표시하지 않으면 무의미한 모호해진다.
yaml
https://medium.com/media/6896daab148cd364501f7a40b8440ce7/href에서 나는 생산량 백서의 불변량을 계산하는 데 도움을 주는 보조 함수를 가지고 있다.나는 다른 곳에서 이 함수를 사용할 것이다. 나는 단독으로 그것을 테스트하고 싶지 않다. 왜냐하면 나는 그것이 상하문 밖에서 작동하는지 확인할 수 없기 때문이다.
this file에서 나는 심지어 변하지 않는 테스트 함수를 가지고 내부화를 통해 주석을 달았다.이것은 개발이 남긴 것이니 깨끗이 정리해야 한다. 얼마나 난처한가.
same file에서 상수가 한 무더기 있는데 모두 내부적이다.만약 그들이 공공적이라면 두더지는 그들의 기능을 고려하여 모호화시킬 것이다. 예를 들어 UNIT처럼 UNIT는 아버지의 계약을 계승하는데 공교롭게도 공공이기 때문에 모호해졌다.
이것은 내가 쓴 첫 번째 모호한 계약이다. 이것은 행운이다. 왜냐하면 창고나 무상태 계약으로서 그것들은 모호하기 쉽기 때문이다.내가 모호화top를 연구하기 시작한 지 얼마 되지 않아, 이것은 나로 하여금 내가 한 모든 일이 매우 틀렸다는 것을 알게 했다.
모호 상태 계약
나는 수학 라이브러리뿐만 아니라 모호하게 상태를 유지하는 계약이 곧 필요하다.생각해 보니 바늘두더지가 진행한 테스트는 고립적으로 진행된 것이 아니었다.
바늘두더지는 고장이 날 때까지 계약의 함수를 무작위로 운행한다.나는 stateful contracts 파일의 seqLen 매개 변수는 하나의 서열에 몇 개의 함수 호출이 있는지 정의해야 한다고 생각한다.
시퀀스에서 상태는 변하지 않습니다.테스트할 계약에서 변하지 않는 계약을 계승하는 것과 달리 더 좋은 방법은 그것들을 한데 연결하는 것이다. 예를 들어 .yaml의 예시와 같다.
contract WETH10Fuzzing {
WETH10 internal weth;
address internal holder;
/// [@dev](http://twitter.com/dev) Instantiate the WETH10 contract, and a holder address
/// that will return weth when asked to.
constructor () {
weth = new WETH10();
holder = address(new MockHolder(address(weth), address(this)));
}
내가 모든 함수를 단독으로 테스트하기 전에, 지금은 상태를 보류했다.바늘두더지는 WETH10에서 함수를 실행하여 실패한 단언을 찾을 것이다.내 불변 테스트 함수는 현재 다음과 같다./// [@dev](http://twitter.com/dev) Test that supply and balance hold on deposit.
function deposit(uint ethAmount) public {
uint supply = weth.totalSupply();
uint balance = weth.balanceOf(address(this));
weth.deposit{value: ethAmount}();
assert(weth.totalSupply() == add(supply, ethAmount));
assert(weth.balanceOf(address(this)) == add(balance, ethAmount));
assert(address(weth).balance == weth.totalSupply());
}
/// [@dev](http://twitter.com/dev) Test that supply and balance hold on withdraw.
function withdraw(uint ethAmount) public {
uint supply = weth.totalSupply();
uint balance = weth.balanceOf(address(this));
weth.withdraw(ethAmount);
assert(weth.totalSupply() == sub(supply, ethAmount));
assert(weth.balanceOf(address(this)) == sub(balance, ethAmount));
assert(address(weth).balance == weth.totalSupply());
}
이것 때문에 저는 WETH10이 이전에 어떤 상태에 있었든지 간에 공급과 잔액은 예금과 인출에 따라 변화할 수 있는지 테스트하고 있습니다.당신은 그것을 사용하여 더욱 복잡한 다중 계약 설정을 구축할 수 있습니다.디버그 모호
모든 테스트가 통과되었을 때, 이것은 매우 좋았다.처음 이런 상황이 발생하지 않으면, 당신은 의심을 품고 테스트 인코딩 오류를 가정해야 합니다.그러니까 일단 테스트를 실패시켜야 돼.
WETH10 우리가 그것을 망가뜨렸어!예!
테스트에 실패했을 때, 두더지는 단언에 실패한 함수를 조합하는 것을 발견할 것이다.그리고 이 고장을 일으키는 가장 짧은 서열을 찾아내서 보통 한 개 혹은 두 개의 호출로 줄일 것이다.바늘두더지가 실행하는 함수 호출을 알려줄 것이다. 이렇게.
로그, 특정 단언에 실패한 정보, 상태 변수의 내용을 얻을 수 없습니다.실패의 원인을 알기란 쉽지 않다.
truffle 컨트롤러나 에서 이 서열을 실행해야 합니다. 이 특정한 사례로 스마트 계약을 검증하고 단언 실패의 원인을 조사할 수 있습니다.
만약 바늘두더지가 나에게 나의'다이를 매입하고 거래를 반전시키는 것'불변량이 어떤 매개 변수에서 실패한다고 알려준다면, 나는 그것들을 테스트 파일에 붙여서 모호한 계약의 동반자로 삼을 것이다.그리고 나는 모든 관련 변수를 저장하고 전통적인 설정에서 디버깅을 시작할 수 있다.
결론
모호함은 쉽지 않고 도구가 거칠고 수학은 어렵지만 가치가 있다.
Fuzzing은 나로 하여금 자신의 스마트 계약에 대해 전대미문의 자신감을 가지게 했다.이제는 단원 테스트와 테스트망에 의존해 돌아다니는 것은 무모한 것 같다.
그렇습니다.이렇게 많을 줄 알았어.이것은 많지 않지만, 나에게 있어서 지금까지의 효과는 매우 좋다.이렇게 멀리 가줘서 고마워요. 행운을 빌어요!
일반 테스트 파일에서 또한 읽으십시오
Crypto Lending Platforms 대 호드나트
Top DeFi Projects — 쉽게 돈을 벌 수 있는 암호화 거래 로봇
Bitsgap review - 전문가를 위한 암호화 거래 로봇
Quadency Review | 우수한 암호화 거래 로봇
Bitmex Advanced Margin Trading Guide 개발업체
Best Crypto APIs 안내: 초보자는 어떻게 돈을 버는가
Crypto Charting Tool
Reference
이 문제에 관하여(지능 계약 모호화), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/coinmonks/smart-contract-fuzzing-1e5c텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)