목차

반응형

1. 개요
2. 블록체인 기본 개념
3. 채굴이 그래서 뭐요?
4. POW란?
5. POW - hashcash
6. 여기서 다시 짚어보는 채굴 행위란?
7. 비트코인 채굴 난이도
8. 채굴 난이도 동적 조절

 

 

 

 

 

 

1. 개요

인터넷에 블록체인의 채굴에 대한 설명이 많은데 대략 어떤 느낌이구나... 싶은 글은 많지만 그런 글들을 읽어도 "그래서 채굴이 뭔데?" 라고 물어보면 비개발자는 물론이고 개발자도 충족시켜줄 만한 답변을 찾기 쉽지 않다.

왜 완벽한 이해가 안됐는지 돌이켜보면 사실 채굴 행위 자체에 대한 의해는 큰 의미가 없으며, 블록체인 세상에서 채굴이라는 행위가 갖는 맥락적인 이해까지 해야 진정한 의미를 알 수 있다.

그래서 일하면서 틈틈이 공부해서 얻어낸 채굴에 대한 전반적인 지식을 정리해서 배포해보도록 하겠다.

 

 

2. 블록체인 기본 개념

비개발자

채굴에 대한 이해를 하기 위해서 최소한 블록체인에 대한 이해를 해야 한다.

 

왜 이런 것이 생겨났냐? 지금 세상의 데이터의 관리 주체는 마치 당신의 핸드폰 정보를 삼성, 아이폰이 갖고 있는 것처럼 특정 개인이 하고 있다.

근데 이것이 맘에 안 들어서 세상 모두가 관리 주체가 되자는 느낌으로 탄생한 이념이 web3며 기반 기술은 블록체인이다. 

"마치 우리 스스로 잘 해낼 수 있다!" 이를 탈중앙화라고 하며 IT계의 무정부주의 같은 느낌이다.

 

네이버 실시간 검색 랭킹

왜 탈중앙화를 해야 하나? 과거 네이버 실시간 검색어에 대한 조작 논쟁이 끊이지 않았던 것 기억하는가?

네이버 실시간 검색 랭킹을 누구도 조작할 수 없도록 시스템을 만든다고 생각하면 된다. 이념이 좀 이해가 되는가?

탈중앙화는 데이터에 대한 투명성을 보장해주며, 이는 곧 시스템에 대한 투명성으로 이어진다.

 

그럼 어떻게 우리 스스로 데이터를 배포하고 관리하느냐?

"데이터를 블록으로 쪼개고 우리 모두가 데이터를 읽는(read) 동시에 쓰면(write) 된다." 라고는 하지만 사실 우리는 읽기(read)만 하고 데이터를 쓰는(write) 사람을 나눠놨다. 그리고 보통 데이터를 쓰는 사람을 채굴자라고 하며 채굴을 통해 데이터를 블록체인상에 올릴 수 있다.

 

개발자

솔직히 블록체인 하도 많이 들어서 이런 얘기는 시시콜콜하죠?

네 압니다. pass

 

3. 채굴이 그래서 뭐요?

말이 길었다. 그래서 채굴이 뭐냐? 6번에서 한번 더 설명할 것이지만 일단 간단히 채굴이 뭔지 에피타이저로 맛보도록 하자.

 

비개발자

돈을 벌고 싶은 누군가가 본인의 컴퓨터를 사용하여 엄청나게 어려운 수학 문제를 푼다.
그 수학 문제를 풀면 블록체인 네트워크상에 데이터를 올릴 수 있는 방법을 알게 되고 그곳에 데이터를 올리고 싶은 사람의 데이터를 받아서 대신 올려준다. 그러면 문제를 풀고 데이터를 올려준 사람은 보상으로 코인을 얻게 된다.
이것이 채굴의 기본적인 의미다.
여기서 어려운 수학 문제를 Proof Of Work라고 하는데 아래에서 POW의 유래와 의미를 알아보도록 하자.

 

개발자

스택오버플로우에서 누군가가 mining을 이렇게 표현했다.
mining is doing the work of finding nonce so that sha256(sha256(data+nonce)) < difficulty
즉 누군가 올리고자 하는 데이터를 받아서 거기에 어떤 난수를 추가해서 해시를 엄청나게 돌리는데 그 해시의 값이 특정 조건을 만족할 때까지 난수를 찾는다.

여기서 만족하는 해시를 찾을 것을 POW라고 하며 다양한 POW가 존재한다. POW의 유래와 정확한 의미를 알아보자.

 

4. POW란?

 

 

POW 의미


Proof Of Work의 의미를 보면 스팸 방지를 위해서 만들어놓은 일정의 지연 장치다.
POW의 유래는 자꾸 스팸메일을 보내서 막기 위해 메일을 요청하기 전에 일정 시간을 쓸 수밖에 없도록 어떠한 조건을 걸어놓은 것이다.




이것을 이해하기 쉽게 비슷한 것을 들고 왔다. 바로 captcha다.
자꾸 사람들이 과도한 반복 요청, 매크로를 하니까 이를 막기 위해 어느 정도 시간이 걸리는 문제를 내는 것인데 거의 비슷하다고 보면 된다.

POW에는 다양한 형태가 있는데 사실 그건 중요하지 않다. POW라는 것이 과도한 요청을 막기 위해 존재한다는 것이 가장 중요하다.

 

비개발자

왜 10분이라는 시간이 지나야 데이터를 쓸 수 있도록 불편하게 설계해놨는지 궁금할 수 있는데 데이터의 읽고 쓰는 것이 너무 쉬워버리면 보안성, 효율성이 떨어지게 된다. 그렇기 때문에 비트코인은 문제를 푸는데 대략 10분이라는 시간이 걸리도록 세팅을 해놨다.

 

개발자

POW의 해결 시간을 왜 평균적으로 10분으로 해놨는지 다양한 의견이 있다. 그중 한 가지 예를 들자면 트랜잭션이 블록체인에 올라가면 전체 네트워크에 전파되기까지 약 1분 정도 걸린다고 한다. 그러면 1분 동안 채굴하기 위해 소모된 리소스가 아무 의미가 없어진다. 만약 10분이라는 시간이 POW의 해결 시간이면 대략 10%의 해시 파워가 낭비된다고 볼 수 있다. 만약에 이 시간이 2분으로 짧아지면? 50%의 해시 파워가 낭비되는 것으로 볼 수 있다.

비트코인은 왜 10분이라는 시간을 트랜잭션의 생성 시간으로 했는지 오래 탐구해봤는데 간단한 내용은 아니라서 추후에 다른 게시물에서 정보를 정리할 생각이다. 일단은 이 정도로만 알고 넘어가자!

따지고 보면 "갓토시 나가모토가 10분으로 해놔서" 가 정답이다 ㅋㅋ

 

5. POW - hashcash

블록체인의 POW에는 다양한 유형이 있다.

한번 알아보자

 

 

그만 알아보자

 

비트코인이 사용하는 POW는 hashcash라고 해서 최초의 작업 증명(POW)이며 유명하다.

비슷한 로직의 소스코드도 널리 퍼져있어서 hashcash POW에 대해서 탐구해보도록 하겠다.

 

비개발자

상식적으로 생각해보면 보통 수학 문제를 낼 때 잘 만든 문제를 내기 위해서는 출제자가 더 오래 고민한다. 그러면 문제를 어떻게 내주길래 고성능의 컴퓨터가 푸는데만 10분이 걸리는 문제를 생성할 수 있는 걸까?

hashcash POW의 원리는 문제의 정답을 알았을 때는 이것이 정답이라는 것을 순식간에 알 수 있지만 정답을 찾는 과정은 아직 현대 기술로는 엄청난 시간이 걸리는 형태의 문제다.

sha256이라는 암호화 기술이 있는데 아무 문자를 암호화시키면 해시 코드라고 해서 규칙성 없는 일련의 코드를 생성한다. 이 해시 코드의 특징은 해시 코드만으로는 원래 문자열이 뭔지 알아내기 힘들지만 원본 문자를 아는 경우 해당 원본 문자가 정말 해시 코드의 원본 데이터인지 진위여부를 판단하는 것은 굉장히 쉽다.

 

여러분의 계정 비밀번호도 위와 같이 암호화를 통하여 DB에 저장된다. 비밀번호 원문을 저장하는 건 법에 걸리기 때문에 여러분이 원문을 입력할 때마다 동일한 암호화를 통하여 해시값이 동일한지 판단하여 로그인을 시켜준다.

그럼 각설하고 POW의 hashcash는 어떤 형태의 값을 찾도록 하는지 말해보겠다.

데이터와 특정 문자를 합쳐서 sha256 암호화를 하면 해시가 생성되는데 그 해시의 맨 앞자리에 0으로 연속된 숫자가 나오도록 하는 것이다.

예를 들면 이번 데이터를 올리기 위해서 맨 앞자리가 0000으로 시작하는 해시를 필요로 하면 컴퓨터는 올리고 싶은 데이터에 랜덤 값을 추가해서 앞자리가 0000인 해시가 될 때까지 계속해서 연산 작업을 하는 것이다.

 

개발자

sha256과 해시에 대해서 충분히 알 것이라고 가정하고 얘기하도록 하겠다.

POW hashcash의 대략적인 로직은 위와 같다. 데이터를 올리고 싶은 사람의 data와 반복될 일 없는 nonce라는 값을 포함시켜서 sha256 해시를 만들고 그 해시의 앞자리에 difficulty 값만큼 0이 반복되는 해시가 나올 때까지 계속해서 돌리는 것이다.

 

6. 여기서 다시 짚어보는 채굴 행위란?

여기서 한번 더 큰 시점으로 채굴이라는 행위에 대한 이해를 해보자.

먼저 데이터를 올리고 싶은 수많은 이용자가 있을 것이고 채굴자는 이 중 수수료가 높은 데이터 위주로 데이터를 넘겨받아 POW를 통하여 해당 데이터를 블록체인상이 올릴 수 있도록 기여를 하고 보상으로 코인을 받는다.

근데 여기서 난이도라는 개념이 빠지면 또 섭섭하기 때문에 마지막은 채굴 난이도에 대하여 설명하면서 마치도록 하겠다.

 

 

 

7. 비트코인 채굴 난이도

채굴이 꿀이라는 소문이 여기저기 퍼지면서 채굴자는 기하급수적으로 늘어나기 시작했다. 채굴자가 많아진다면 아무래도 문제를 푸는 데 걸리는 시간은 더 짧아질 수밖에 없다. 하지만 비트코인은 채굴자가 많아지더라도 해당 상황을 인지하여 POW 문제를 해결하는 데 걸리는 시간을 절대적으로 동일할 수 있도록 난이도를 가변 변수로 설정해놨다. 즉 채굴자가 많아질수록 난이도가 높아지는 것이고 그렇게 되면 아까 POW에서 필요로 하는 앞자리 0의 개수를 점차 늘리는 것이다.

 

위 사이트는 과거 비트코인 채굴자의 채굴 이력을 볼 수 있는 페이지다.

해시를 보면 앞자리 0이 들어가 있는 것을 볼 수 있고 아래 당시 채굴 난이도(Difficulty)도 적혀있다.

 

위 그래프는 비트코인의 채굴 난이도를 의미한다. t는 trillion으로 조를 의미하며 난이도가 비트코인이 꿀이라는 소식이 여기저기 퍼지면서 점차 난이도가 상승하는 것을 볼 수 있다.

난이도가 상승할수록 채굴 대비 떨어지는 수익률이 줄어들기 때문에 자연스럽게 개인 채굴자는 줄어들 것이며 대형 채굴업체들이 다 같이 만족할 만큼의 인프라가 형성될 것이다.

채굴 비용이 너무 과하면 자연스럽게 채굴자가 줄어들 것이고 채굴 효율이 너무 좋으면 다시 채굴자가 늘어날 것이기 때문에 난이도라는 가변 변수 앞에 인간들이 통제된다고 볼 수 있다.(??)

 

위 사진은 난이도에 따른 해시값에 대한 예시다. POW - hashcash 방식이 대충 이런 느낌으로 돌아간다고 보면 된다.

 

8. 채굴 난이도 동적 조절

그럼 여기서 궁금한 것이 있다. 비트코인은 어떻게 난이도를 가변 변수로 설정해놨을까?

굉장히 복잡할 것 같지만 엄청 간단한 로직이라서 채굴 난이도 동적 조절에 대한 개념적인 부분까지 설명하고자 한다.

 

비개발자

채굴이 정상적으로 이뤄질 때마다 당시 시간이 기록된다.

비트코인의 이상적인 채굴 시간은 10분으로 설정되어 있는데 100번째 채굴이 10시 30분에 이뤄졌고 101번째 채굴이 10시 35분에 이뤄졌다면 예상했던 것보다 5분 빠르게 채굴된 것이기 때문에 난이도가 너무 쉬워졌다고 볼 수 있다.

블록체인 네트워크는 인지하여 난이도를 올리고 다음 블록은 해당 난이도를 반영하여 채굴하게 된다.

 

 

위의 그림과 같이 채굴이 너무 빠르면 난이도를 높여주고 채굴이 너무 오래 걸리면 난이도를 줄여주는 것을 볼 수 있다.

반응형
반응형

이번에 할 작업

생성한 릴레이 서버 정상 작동하는지 확인

 

따라 하기

전제 필요조건 : 유니티 월렛커넥트 SDK 연동된 프로젝트가 있어야 함.

 

본인의 도메인으로 직접 테스트 가능하다.

https://bridge.당신의도메인/hello 했을때 위와 같이 나오면 정상이다.

https://bridge.당신의도메인 이 주소를 릴레이서버 주소로 사용하면 된다.

 

유니티에서도 다음과 같이 사용 가능하다.

 

 

정상 작동한다.

굿

 

여담으로 Walletconnect 디스코드 채널에 세바스찬 아저씨가 있는데 이 아저씨가 릴레이 서버 설치 관련해서 문의를 담당하시는 것 같다.

도중에 나를 읽씹해버려서 큰 도움은 안되었으나 궁금한거 있으면 이 사람한테 물어보면 될듯!

 

 

Walletconnect 릴레이서버 배포 관련 정보

월렛커넥트 깃 주소 : https://github.com/WalletConnect/walletconnect-monorepo

월렛커넥트 디스코드 주소 : https://discord.com/invite/cB54BwPGru

 

월렛커넥트 릴레이서버 배포 관련 게시물

WalletConnect 릴레이 서버 만들기 - 1 Godday Cloudflare 연동

WalletConnect 릴레이 서버 만들기 - 2 GCP 서버프로젝트 세팅

WalletConnect 릴레이 서버 만들기 - 3 릴레이 서버 배포

WalletConnect 릴레이 서버 만들기 - 4 릴레이 서버 테스트

반응형
반응형

이번에 할 작업

Cloudflare 나머지 설정, 릴레이 서버 배포

 

따라 하기

클라우드플레어 > DNS 설정

 

Record를 위와 같이 3개 설정해야 한다.

본인 도메인이 relaynetwork.com이라면 Name에 bridge, relaynetwork.com, www가 들어가야 한다.

content에는 GCP에서 생성한 인스턴스의 외부 IP를 기입하도록 하자.

Proxy status는 전부 DNS only로 설정

 

 

https://dash.cloudflare.com/profile

위 링크로 들어가서 API Tokens 클릭

 

Create Token 클릭

 

Edit zone DNS > Use template 클릭

 

전부 그대로 두고 Zone Resources의 마지막 부분에 본인의 도메인을 선택

 

Continue 클릭

 

Create Token 클릭

 

토큰을 복사하고 어딘가에 저장해 두자.

다시 조회 못함

 

다시 GCP 프로젝트로 돌아와서 릴레이서버 프로젝트 루트에서 sudo make deploy 명령어 실행

이후 URL domain, Email, cloudflare API token 3개의 값을 입력해야 한다.

 

만약 본인의 도메인이 relaynetwork.com이면 아래와 같이 입력하면 된다.

Relay URL domain : bridge.relaynetwork.com

Email : 그냥 비우고 엔터

cloudflare API token : 발급받았던 토큰 입력

 

3가지 값을 입력하고 기다리면 알아서 열심히 설치한다.

한 20~30분 정도 걸림.

 

설치가 끝났다.

 

sudo docker ps 명령어로 구동 중인 도커 컨테이너를 확인해보자.

위와 같이 나오면 정상이다.

 

Walletconnect 릴레이서버 배포 관련 정보

월렛커넥트 깃 주소 : https://github.com/WalletConnect/walletconnect-monorepo

월렛커넥트 디스코드 주소 : https://discord.com/invite/cB54BwPGru

 

월렛커넥트 릴레이서버 배포 관련 게시물

WalletConnect 릴레이 서버 만들기 - 1 Godday Cloudflare 연동

WalletConnect 릴레이 서버 만들기 - 2 GCP 서버프로젝트 세팅

WalletConnect 릴레이 서버 만들기 - 3 릴레이 서버 배포

WalletConnect 릴레이 서버 만들기 - 4 릴레이 서버 테스트

반응형
반응형

이번에 할 작업

GCP 프로젝트 생성, 필수 라이브러리 설치, 릴레이 서버 Git 프로젝트 클론

 

따라 하기

전제 필요조건 : GCP 계정, 본인 컴퓨터에 gcloud 설치

 

GCP 프로젝트를 생성하도록 하자.

인스턴스 만들기 클릭

 

이름 적당히 정하고 리전은 본인 상황에 맞춰서 설정하자.

 

부팅 디스크 변경

 

운영체제와 버전 크기를 다음과 같이 설정하자

 

HTTP, HTTPS 둘 다 미리 체크하고 만들기 클릭

 

인스턴스 생성되면 glcoud 명령어 보기 클릭

 

명령어 복사

 

gcloud 명령어로 ssh 연결, gcloud 설치 안됐으면 하고오셈

 

Accept

 

정상적으로 접속

 

sudo apt-get update && sudo apt-get-upgrade -y

apt 업데이트

 

sudo apt-get install git -y && sudo apt-get install make -y && sudo apt-get install curl -y

Git, Make, Curl 설치

 

curl -fSL https://get.docker.com -o get-docker.sh

도커 설치 sh 파일 다운로드

 

sudo sh ./get-docker.sh

도커 설치 스크립트 실행

 

sudo service docker start

sudo docker swarm init

도커 서비스 시작, 도커 swarm 설정

 

sudo docker ps

도커 서비스 정상 작동하는지 확인

 

git clone https://github.com/WalletConnect/walletconnect-monorepo.git

월렛커넥트 git 클론

 

깃 클론 완료

 

최신 버전 작동 안 해서 위 커밋 내역 확인해서 클릭

 

해당 커밋 해시값 복사

 

git checkout 해시값

정상작동하는 커밋 버전으로 롤백

 

깃 프로젝트 루트에서 vi Makefile을 해서 Makefile을 까 보면 build-images라는 명령어가 있는데 거기에 build-img-caddy가 있는지 확인

 

Walletconnect 릴레이서버 배포 관련 정보

월렛커넥트 깃 주소 : https://github.com/WalletConnect/walletconnect-monorepo

월렛커넥트 디스코드 주소 : https://discord.com/invite/cB54BwPGru

 

월렛커넥트 릴레이서버 배포 관련 게시물

WalletConnect 릴레이 서버 만들기 - 1 Godday Cloudflare 연동

WalletConnect 릴레이 서버 만들기 - 2 GCP 서버프로젝트 세팅

WalletConnect 릴레이 서버 만들기 - 3 릴레이 서버 배포

WalletConnect 릴레이 서버 만들기 - 4 릴레이 서버 테스트

반응형
반응형

개요

블록체인 Dapp을 만들기 위해서 지갑 연동 라이브러리를 써야 하는데 WalletConnect를 많이 쓰는 것 같다.

근데 월렛커넥트 Dapp을 만들다 보면 유니티에서 예시용으로 사용하는 릴레이 서버를 사용해서 로그인하면 불안정해서 WalletConnect 측에서 제공한 코드를 사용해서 릴레이 서버를 직접 만들어야 한다.

https://github.com/WalletConnect-Labs/walletconnect-v2-monorepo

 

문제는 설명이 불친절해서 초고교급 인프라 능력자가 아니면 엄청 삽질해야 한다.

본인은 이거 구축하는데 2주 걸렸다...

솔직히 블로깅 해도 읽을 사람 별로 없는 내용인 거 나도 아는데 그냥 쓰고 싶어서 써본다.

이 글을 읽는 당신 나한테 굉장히 감사해라

 

이번에 할 작업

이번 릴레이 서버 구축 1편에서 할 작업은 Godaddy의 도메인과 Cloudflare를 연동하는 것이다.

 

따라 하기

전제 필요조건 : 도메인 필요, Cloudflare 계정

 

Cloudflare에서 본인이 구매한 도메인을 입력하고 Add site를 한다.

ex) relaynetwork.com

 

free plan 선택 후 Continue 누른다

 

그러면 DNS 탐색한다고 한다. 기다린다.

 

그러면 건들지 말고 Continue 누른다.

 

 

그러면 Godaddy에서 빨간색 부분은 지우라고 하고 파란색 부분을 추가하라고 한다.

 

Godaddy에서 도메인 즉당한거 사고 관리 페이지에서 ... 눌러서 DNS 관리로 들어간다.

 

네임서버 > 변경 클릭

 

내 자신의 네임서버 입력

 

아까 추가해달라고 한 2개 주소를 추가해준다.

 

체크하고 계속

 

다시 Cloudflare로 돌아가서 Done check nameserver 클릭

 

하단의 check nameservers 클릭

 

기다리라고 한다.

 

조금만 기다리면 위와 같이 연결 성공했다고 알려준다.

 

Walletconnect 릴레이서버 배포 관련 정보

월렛커넥트 깃 주소 : https://github.com/WalletConnect/walletconnect-monorepo

월렛커넥트 디스코드 주소 : https://discord.com/invite/cB54BwPGru

 

월렛커넥트 릴레이서버 배포 관련 게시물

WalletConnect 릴레이 서버 만들기 - 1 Godday Cloudflare 연동

WalletConnect 릴레이 서버 만들기 - 2 GCP 서버프로젝트 세팅

WalletConnect 릴레이 서버 만들기 - 3 릴레이 서버 배포

WalletConnect 릴레이 서버 만들기 - 4 릴레이 서버 테스트

 

 

 

 

 

반응형
반응형

증상

nodejs의 web3 라이브러리를 사용하여 스마트컨트랙트로 구현한 이벤트를 구독하는데 시간이 지나면 이벤트 리스닝이 끊기는 경우가 있다.

 

원인

원인은 web3 프로바이더를 설정할때 옵션으로 프로바이더의 통신이 끊기지 않도록 설정해주지 않아서 그렇다.

 

인터넷에 보통 아래 2개 형태의 코드가 떠돌아다니는데 프로바이더 설정에 대한 내용이 빠져있다.

const Web3 = require('web3');
require('dotenv').config()

// ENTER A VALID RPC URL!
const web3 = new Web3(process.env.NODE_URL);

//ENTER SMART CONTRACT ADDRESS BELOW. see abi.js if you want to modify the abi
const CONTRACT_ADDRESS = "0xE1C8f3d529BEa8E3fA1FAC5B416335a2f998EE1C";
const CONTRACT_ABI = require('./abi.json');
const contract = new web3.eth.Contract(CONTRACT_ABI, CONTRACT_ADDRESS);

async function getEvents() {
    let latest_block = await web3.eth.getBlockNumber();
    let historical_block = latest_block - 10000; // you can also change the value to 'latest' if you have a upgraded rpc
    console.log("latest: ", latest_block, "historical block: ", historical_block);
    const events = await contract.getPastEvents(
        'Transfer', // change if your looking for a different event
        { fromBlock: historical_block, toBlock: 'latest' }
    );
    await getTransferDetails(events);
};

async function getTransferDetails(data_events) {
    for (i = 0; i < data_events.length; i++) {
        let from = data_events[i]['returnValues']['from'];
        let to = data_events[i]['returnValues']['to'];
        let amount = data_events[i]['returnValues']['amount'];
        let converted_amount = web3.utils.fromWei(amount);
        if (converted_amount > 32) { //checking for transcations with above 32 eth as an example
            console.log("From:", from, "- To:", to, "- Value:", converted_amount);
        }
    };
};


getEvents(CONTRACT_ABI, CONTRACT_ADDRESS);
var Web3 = require('web3');
var abi = '...';
var contractAddress = '0x62e7Dd1Af52d5A08D401b1e156cC4CB1d2f89d57';
var eventName = 'Transfer';
//var web3;
var etat;
const web3 = new Web3(new Web3.providers.WebsocketProvider('http://127.0.0.1:8545'));
/*
var MyContract = new web3.eth.Contract(JSON.parse(abi));
var myContractInstance = MyContract.at('0x78e97bcc5b5dd9ed228fed7a4887c0d7287344a9');

// watch for an event with {some: 'args'}
var myEvent = myContractInstance.Transfer({}, {fromBlock: 0, toBlock: 'latest'});
myEvent.watch(function(error, result){
    console.log(result)
});

// would get all past logs again.
var myResults = myEvent.get(function(error, logs){ console.log(logs) });



// would stop and uninstall the filter
myEvent.stopWatching();
*/



var TokenContract = new web3.eth.Contract(JSON.parse(abi),contractAddress);
TokenContract.events.allEvents({ fromBlock: 'latest' }, console.log)
console.log('1********************************************************************************')
console.log(TokenContract);
console.log('2********************************************************************************')
var event = TokenContract.events.Transfer();
console.log(event);
console.log('3********************************************************************************')

TokenContract.once('Transfer', {
}, function(error, event){ console.log(event); });

event.watch(function(error, result){
    if (!error) {
        alert("wait for a while, check for block Synchronization or block creation");
        console.log(result);
        console.log('pas d erreur');
    }else {
        console.log(error);
        console.log('erreur')
    }
});

 

해결방법

웹3 프로바이더 인스턴스 생성 시 옵션 정보를 넣어주는 것으로 해결 가능하다.

아래와 같이 코드를 짜면 해결된다. 추가로 web3-provider-ws 라는 라이브러리를 사용했다.

var express = require('express');
var router = express.Router();
const { item, itemPreset } = require('../models');
const debug = (...messages) => console.log(...messages)

var Web3WsProvider = require('web3-providers-ws');
var Web3 = require('web3');
const options = {
    timeout: 30000, // ms

    clientConfig: {
        // Useful if requests are large
        maxReceivedFrameSize: 100000000,   // bytes - default: 1MiB
        maxReceivedMessageSize: 100000000, // bytes - default: 8MiB

        // Useful to keep a connection alive
        keepalive: true,
        keepaliveInterval: 60000 // ms
    },

    // Enable auto reconnection
    reconnect: {
        auto: true,
        delay: 5000, // ms
        maxAttempts: 5,
        onTimeout: false
    }
};

var web3 = new Web3();
web3.setProvider(new Web3WsProvider('wss://speedy-nodes-nyc.moralis.io/12341234/bsc/mainnet/ws', options));

const contract = require("../artifacts/contracts/Furniture.sol/Furniture.json")
const googleCloudStorage = require("../scripts/googleCloudStorage");
const contractAddress = process.env.contractAddress
const nftContract = new web3.eth.Contract(contract.abi, contractAddress)


var eventMintFurniture = nftContract.events.eventMint({}).on("data", async event => {
    console.log("Mint")
    let result = event.returnValues
    let msgSender = result[0]
    let tokenId = parseInt(result[1])
    // ... your logic

}).on("connected", event => {
    console.log('eventMintFurniture connected')
}).on("error", event => {
    console.log('eventMintFurniture error')
    console.log(event)
}).on("end", event => {
    refreshProvider(web3, 'wss://ropsten.infura.io/ws/v3/925d17c78a0b41f5907df58579ce44bd')
    console.log("eventMintFurniture end")
})

 

 

참고

https://web3js.readthedocs.io/en/v1.5.2/web3-eth.html#configuration

반응형
반응형

증상

가나슈를 작동해서 노드를 가동하고 truffle로 붙어서 스마트컨트랙트의 함수를 실행하거나 컴파일을 하면 아래와 같이 오류가 뜨면서 작동하지 않는다.

 

Saving migration to chain.
Error: Returned error: VM Exception while processing transaction: invalid opcode
    at Migration._deploy (************************\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\Migration.js:99:1)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at Migration._load (************************\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\Migration.js:56:1)
    at Migration.run (************************\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\Migration.js:217:1)
    at Object.runMigrations (************************\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\index.js:150:1)
    at Object.runFrom (************************\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\index.js:110:1)
    at Object.runAll (************************\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\index.js:114:1)
    at Object.run (************************\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\migrate\index.js:79:1)
    at runMigrations (************************\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\core\lib\commands\migrate.js:258:1)
    at Object.run (************************\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\core\lib\commands\migrate.js:223:1)
    at Command.run (************************\AppData\Roaming\npm\node_modules\truffle\build\webpack:\packages\core\lib\command.js:183:1)
Truffle v5.4.24 (core: 5.4.24)
Node v16.13.1
PS ************************\Desktop\project\blockchain\realestate>

 

원인

본인은 가나슈 gui 버전을 돌리는데 cli 버전으로 돌리면 괜찮다는 글을 봤다.

gui 가나슈의 버그라고 한다.

 

해결방법

가나슈 gui가 아닌 cli를 설치해서 가동한다.

 

npm install ganache-cli

위 명령어로 가나슈 cli를 설치한다.

 

ganache-cli -a

cmd를 켜서 가나슈 노드를 작동하고 이전에 했던것처럼 명령어를 가동한다.

 

잘된다.

 

아래 링크 참고

https://ethereum.stackexchange.com/questions/83222/vm-exception-while-processing-transaction-invalid-opcode-error

 

vm exception while processing transaction: invalid opcode error

I've been running this code on remix ide on injected web3 with my ganache server in on state, then also i'm getting this error of invalid opcode. The code runs perfectly in rinkeby test network. p...

ethereum.stackexchange.com

 

반응형
반응형

증상

truffle develop --log

명령어를 사용하면 트러플 노드의 로그가 쌓여야하는데 전혀 로그가 안쌓인다.

 

 

원인

관리자 권한으로 하지 않아서 그렇다.

 

해결방법

관리자 권한으로 실행하고 다시한번 해보자.

잘된다.

반응형
반응형

증상

3

geth 명령어 사용시 flag provided but not defined: -rpc와 같은 에러메시지가 발생한다.

 

원인

geth 사용시 버전에 따라 명령어의 파라미터 이름이 다르다.

flag provided but not defined: -rpc는 rpc라는 파라미터 이름이 http로 교체되어서 발생하는 메시지다.

 

해결방법

--rpc => --http 로 바꿔줘야한다.

 

비슷한 사례

--minerthreads =>  --miner.threads

--rpcport는 => --http.port

--rpccorsdomain => --http.corsdomain

 

본인이 써야하는 파라미터의 이름은 아래링크가서 2개 참고하면서 직접 찾아서 바꾸도록 하자.

https://stackoverflow.com/questions/69463898/flag-provided-but-not-defined-rpc

https://geth.ethereum.org/docs/interface/command-line-options

 

 

 

geth --networkid 4386 --mine --miner.threads 2 --datadir "./" --nodiscover --http --http.port "8545" --http.corsdomain "*" --nat "any" --http.api eth,web3,personal,net --password ./password.sec

 

반응형
반응형

증상

솔리디티 컴파일 도중 payable 함수를 사용할때 아래와 같은 에러메시지를 받는다.

 

Desktop\project\token>npx hardhat run ./scripts/deploy.js --network ropsten
Compiling 1 file with 0.8.0
ParserError: Expected a state variable declaration. If you intended this as a fallback function or a function to handle plain ether transactions, use the "fallback" keyword or the "receive" keyword instead.
   --> contracts/HITO.sol:150:32:
    |
150 |     function () public payable {
    |                                ^


Error HH600: Compilation failed

For more info go to https://hardhat.org/HH600 or run Hardhat with --show-stack-traces

 

 

 

원인

솔리디티 버전이 올라가면서 payable 함수는 function이 아니라 fallback으로 수현해야한다.

 

해결방법

아래와 같이 수정하면 된다.

 

 

참고 링크

https://ethereum.stackexchange.com/questions/89833/compiler-solc-expected-a-state-variable-declaration

 

Compiler solc expected a state variable declaration

I try example from book Mastering Ethereum: contract Faucet { function withdraw(uint withdraw_amount) public { require(withdraw_amount<=10000000000000000); msg.sender.transfer(

ethereum.stackexchange.com

 

반응형