<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>uzzam.dev</title>
    <link>https://uzzam.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Fri, 5 Jun 2026 22:49:52 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>uzzam</managingEditor>
    <item>
      <title>Built build/app/outputs/flutter-apk/app-debug.apk 에서 멈출 때</title>
      <link>https://uzzam.tistory.com/63</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;ios simulator 에서는 잘되는데 안드로이드 시뮬레이터에서는 안되는 경우가 종종 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 외주를 받으면서 다양한 상황을 겪었는데 그 중 하나는 앱은 빌드가 되는데&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;콘솔창에서 보면 아래와 같은 화면에 멈춰 있고, 설치된 앱을 실행시켜도 바로 꺼지는 경우가 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1725288037209&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Launching lib/main.dart on sdk gphone64 arm64 in debug mode...
✓ Built build/app/outputs/flutter-apk/app-debug.apk&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 또한 다양한 원인이 있지만, 두 번 이상 겪은 문제로 봤을 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;android/app/src/main/.../MainActivity.kt 에 있는 package 이름과&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;android/app/build.gradle 의 namespace 이름이 다른지 꼭 확인해봐야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 두개는 같아야 한다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 해결법들은 아래에서 확인 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/53394504/flutter-stuck-at-installing-build-app-outputs-apk-app-apk?page=2&amp;amp;tab=scoredesc&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://stackoverflow.com/questions/53394504/flutter-stuck-at-installing-build-app-outputs-apk-app-apk?page=2&amp;amp;tab=scoredesc&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1725288201705&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Flutter stuck at Installing build\app\outputs\apk\app.apk&quot; data-og-description=&quot;When I run: $ flutter run I'm getting a prompt on my mobile device asking if I want to install the app on my device. I give yes, then nothing happens! It's stuck here: Launching lib/main.dart on P...&quot; data-og-host=&quot;stackoverflow.com&quot; data-og-source-url=&quot;https://stackoverflow.com/questions/53394504/flutter-stuck-at-installing-build-app-outputs-apk-app-apk?page=2&amp;amp;tab=scoredesc&quot; data-og-url=&quot;https://stackoverflow.com/questions/53394504/flutter-stuck-at-installing-build-app-outputs-apk-app-apk&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/iHzaY/hyWZc9ciTW/GU1mH692L6U5aDojmTMxD1/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/53394504/flutter-stuck-at-installing-build-app-outputs-apk-app-apk?page=2&amp;amp;tab=scoredesc&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stackoverflow.com/questions/53394504/flutter-stuck-at-installing-build-app-outputs-apk-app-apk?page=2&amp;amp;tab=scoredesc&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/iHzaY/hyWZc9ciTW/GU1mH692L6U5aDojmTMxD1/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Flutter stuck at Installing build\app\outputs\apk\app.apk&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;When I run: $ flutter run I'm getting a prompt on my mobile device asking if I want to install the app on my device. I give yes, then nothing happens! It's stuck here: Launching lib/main.dart on P...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;stackoverflow.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>frameworks/flutter</category>
      <author>uzzam</author>
      <guid isPermaLink="true">https://uzzam.tistory.com/63</guid>
      <comments>https://uzzam.tistory.com/63#entry63comment</comments>
      <pubDate>Mon, 2 Sep 2024 23:43:51 +0900</pubDate>
    </item>
    <item>
      <title>플러터 vscode 멀티 디바이스 디버깅</title>
      <link>https://uzzam.tistory.com/62</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;플러터로 앱 개발시 여러 디바이스에서 동시에 디버깅을 하는 것은 매우 유용하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러터가 크로스 플랫폼 프레임워크인 만큼 여러 개의 플랫폼에 출시할 가능성이 높고, 이 때문에 안드로이드 / ios 두 개의 시뮬레이터를 동시에 띄워놓고 각각 플랫폼 별 상태를 확인한다던지, 아니면 시뮬레이터와 실제 기기의 경험이 분명 다르기 때문에 시뮬레이터 / 실제 기기를 동시에 띄워놓고 작업한다면 굉장히 효율적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러개의 디바이스에서 디버깅하는 방법은 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 실행을 원하는 deviceId 구하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. vscode launch.json 작성하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 실행하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방법이 굉장히 쉽고 간단하다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 실행을 원하는 deviceId 구하기&lt;/h3&gt;
&lt;pre id=&quot;code_1721232897108&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;flutter devices&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;터미널에 명령어를 입력하면 현재 연결된 기기들의 device id를 구할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같은 형식으로 deviceId가 나온다.&lt;/p&gt;
&lt;pre id=&quot;code_1721233170187&quot; class=&quot;angelscript&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;{기기이름} &amp;bull; {deviceId} &amp;bull; ios &amp;bull; iOS
  17.5.1 21F90
{기기이름} &amp;bull; {deviceId} &amp;bull; ios &amp;bull; iOS
  17.5.1 21F90&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. vscode launch.json 작성하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 폴더에 최상단에 .vscode 폴더를 만들어주고 launch.json 파일을 만들어 아래와 같이 작성해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1721233302490&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
	&quot;version&quot;: &quot;0.2.0&quot;,
	&quot;configurations&quot;: [
		{
			&quot;name&quot;: &quot;Current Device&quot;,
			&quot;request&quot;: &quot;launch&quot;,
			&quot;type&quot;: &quot;dart&quot;
		},
		{
			&quot;name&quot;: &quot;{설정하고 싶은 별명 ex) Android}&quot;,
			&quot;request&quot;: &quot;launch&quot;,
			&quot;type&quot;: &quot;dart&quot;,
			&quot;deviceId&quot;: &quot;{deviceId}&quot;
		},
		{
			&quot;name&quot;: &quot;{설정하고 싶은 별명 ex) iPhone}&quot;,
			&quot;request&quot;: &quot;launch&quot;,
			&quot;type&quot;: &quot;dart&quot;,
			&quot;deviceId&quot;: &quot;{deviceId}&quot;
		},
	],
	&quot;compounds&quot;: [
		{
			&quot;name&quot;: &quot;All Devices&quot;,
			&quot;configurations&quot;: [&quot;Android&quot;, &quot;iPhone&quot;],
		}
	]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 실행하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vscode 에서 사진 상 1번에 해당하는 RUN AND DEBUG 탭으로 가준 뒤&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2번에서 목록을 펼쳐보면 실행 가능한 설정이 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목록에서 All Devices 를 선택하게 된다면 launch.json 기준으로 Android, iPhone 에 해당하는 기기들이 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초록색 버튼을 누르게 되면 해당 설정으로 바로 실행된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;555&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5qhDj/btsIElM5OTK/KIiHgu07ED2L8foqqKGjg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5qhDj/btsIElM5OTK/KIiHgu07ED2L8foqqKGjg0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5qhDj/btsIElM5OTK/KIiHgu07ED2L8foqqKGjg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5qhDj%2FbtsIElM5OTK%2FKIiHgu07ED2L8foqqKGjg0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;355&quot; height=&quot;521&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;555&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;4. 끝&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 각각 기기를 선택하여서 핫리로드나 핫리스타트를 할 수 있고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 기기에 해당하는 debug console 을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-18 오전 1.33.30.png&quot; data-origin-width=&quot;354&quot; data-origin-height=&quot;62&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceyDnD/btsIEv9QEWh/1qWECKwCn2Zps2PjGVgDq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceyDnD/btsIEv9QEWh/1qWECKwCn2Zps2PjGVgDq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceyDnD/btsIEv9QEWh/1qWECKwCn2Zps2PjGVgDq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceyDnD%2FbtsIEv9QEWh%2F1qWECKwCn2Zps2PjGVgDq0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;354&quot; height=&quot;62&quot; data-filename=&quot;스크린샷 2024-07-18 오전 1.33.30.png&quot; data-origin-width=&quot;354&quot; data-origin-height=&quot;62&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-18 오전 1.33.52.png&quot; data-origin-width=&quot;1416&quot; data-origin-height=&quot;60&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/R4Eez/btsICjjgctt/zDV8teSvmOyYsDMPdmrVz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/R4Eez/btsICjjgctt/zDV8teSvmOyYsDMPdmrVz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/R4Eez/btsICjjgctt/zDV8teSvmOyYsDMPdmrVz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FR4Eez%2FbtsICjjgctt%2FzDV8teSvmOyYsDMPdmrVz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1416&quot; height=&quot;60&quot; data-filename=&quot;스크린샷 2024-07-18 오전 1.33.52.png&quot; data-origin-width=&quot;1416&quot; data-origin-height=&quot;60&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;참고자료&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/flutter/flutter/wiki/Multi-device-debugging-in-VS-Code&quot;&gt;https://github.com/flutter/flutter/wiki/Multi-device-debugging-in-VS-Code&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1721233842924&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;Multi device debugging in VS Code&quot; data-og-description=&quot;Flutter makes it easy and fast to build beautiful apps for mobile and beyond - flutter/flutter&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/flutter/flutter/wiki/Multi-device-debugging-in-VS-Code&quot; data-og-url=&quot;https://github.com/flutter/flutter/wiki/Multi-device-debugging-in-VS-Code&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mqVWa/hyWCMC1zLG/TTMW6p44qxRcvfDHWICXCk/img.png?width=1386&amp;amp;height=640&amp;amp;face=0_0_1386_640&quot;&gt;&lt;a href=&quot;https://github.com/flutter/flutter/wiki/Multi-device-debugging-in-VS-Code&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/flutter/flutter/wiki/Multi-device-debugging-in-VS-Code&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mqVWa/hyWCMC1zLG/TTMW6p44qxRcvfDHWICXCk/img.png?width=1386&amp;amp;height=640&amp;amp;face=0_0_1386_640');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Multi device debugging in VS Code&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Flutter makes it easy and fast to build beautiful apps for mobile and beyond - flutter/flutter&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>frameworks/flutter</category>
      <category>flutter</category>
      <category>디버깅</category>
      <category>멀티디바이스</category>
      <author>uzzam</author>
      <guid isPermaLink="true">https://uzzam.tistory.com/62</guid>
      <comments>https://uzzam.tistory.com/62#entry62comment</comments>
      <pubDate>Thu, 18 Jul 2024 01:36:52 +0900</pubDate>
    </item>
    <item>
      <title>Geth 소스코드 분석 4 - makeFullNode 1편 - makeConfigNode()</title>
      <link>https://uzzam.tistory.com/59</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;저번 글에서 geth 클라이언트를 실행하면 크게 세 가지 함수인 prepare, makeFullNode, startNode가 실행되는 것을 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서는 makeFullNode 함수를 볼 예정이다.&lt;/p&gt;
&lt;pre id=&quot;code_1707002018798&quot; class=&quot;go&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;// makeFullNode loads geth configuration and creates the Ethereum backend.
func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;makeFullNode 함수의 주석을 보면 geth 설정을 불러오고 이더리움 백엔드를 만든다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이더리움 백엔드는 타입에 대해 다룬 두 번째 글에서 살펴본 backend 타입을 생각하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cli.Context를 받아서 node.Node와 ethapi.Backend를 리턴해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 전체 코드를 한 번 보자&lt;/p&gt;
&lt;pre id=&quot;code_1707002201288&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// makeFullNode loads geth configuration and creates the Ethereum backend.
func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
	stack, cfg := makeConfigNode(ctx)
	if ctx.IsSet(utils.OverrideCancun.Name) {
		v := ctx.Uint64(utils.OverrideCancun.Name)
		cfg.Eth.OverrideCancun = &amp;amp;v
	}
	if ctx.IsSet(utils.OverrideVerkle.Name) {
		v := ctx.Uint64(utils.OverrideVerkle.Name)
		cfg.Eth.OverrideVerkle = &amp;amp;v
	}
	backend, eth := utils.RegisterEthService(stack, &amp;amp;cfg.Eth)

	// Create gauge with geth system and build information
	if eth != nil { // The 'eth' backend may be nil in light mode
		var protos []string
		for _, p := range eth.Protocols() {
			protos = append(protos, fmt.Sprintf(&quot;%v/%d&quot;, p.Name, p.Version))
		}
		metrics.NewRegisteredGaugeInfo(&quot;geth/info&quot;, nil).Update(metrics.GaugeInfoValue{
			&quot;arch&quot;:      runtime.GOARCH,
			&quot;os&quot;:        runtime.GOOS,
			&quot;version&quot;:   cfg.Node.Version,
			&quot;protocols&quot;: strings.Join(protos, &quot;,&quot;),
		})
	}

	// Configure log filter RPC API.
	filterSystem := utils.RegisterFilterAPI(stack, backend, &amp;amp;cfg.Eth)

	// Configure GraphQL if requested.
	if ctx.IsSet(utils.GraphQLEnabledFlag.Name) {
		utils.RegisterGraphQLService(stack, backend, filterSystem, &amp;amp;cfg.Node)
	}
	// Add the Ethereum Stats daemon if requested.
	if cfg.Ethstats.URL != &quot;&quot; {
		utils.RegisterEthStatsService(stack, backend, cfg.Ethstats.URL)
	}
	// Configure full-sync tester service if requested
	if ctx.IsSet(utils.SyncTargetFlag.Name) {
		hex := hexutil.MustDecode(ctx.String(utils.SyncTargetFlag.Name))
		if len(hex) != common.HashLength {
			utils.Fatalf(&quot;invalid sync target length: have %d, want %d&quot;, len(hex), common.HashLength)
		}
		utils.RegisterFullSyncTester(stack, eth, common.BytesToHash(hex))
	}
	// Start the dev mode if requested, or launch the engine API for
	// interacting with external consensus client.
	if ctx.IsSet(utils.DeveloperFlag.Name) {
		simBeacon, err := catalyst.NewSimulatedBeacon(ctx.Uint64(utils.DeveloperPeriodFlag.Name), eth)
		if err != nil {
			utils.Fatalf(&quot;failed to register dev mode catalyst service: %v&quot;, err)
		}
		catalyst.RegisterSimulatedBeaconAPIs(stack, simBeacon)
		stack.RegisterLifecycle(simBeacon)
	} else {
		err := catalyst.Register(stack, eth)
		if err != nil {
			utils.Fatalf(&quot;failed to register catalyst service: %v&quot;, err)
		}
	}
	return stack, backend
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;makeFullNode 함수에서 실행하는 함수는 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- makeconfigNode&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RegisterEthService&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RegisterFilterAPI&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RegisterGraphQLService&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RegisterEthStatsService&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RegisterFullSyncTester&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RegisterSimulatedBeaconAPIs&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RegisterLifecycle&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이름에서 볼 수 있듯이 register 해주는게 makeFullNode 함수의 역할이라고 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;makeFullNode의 반환 타입인 Node 와 Backend 는 어디서 올까?&lt;/p&gt;
&lt;pre id=&quot;code_1707397277468&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// makeFullNode loads geth configuration and creates the Ethereum backend.
func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
	stack, cfg := makeConfigNode(ctx)
    // 생략
	backend, eth := utils.RegisterEthService(stack, &amp;amp;cfg.Eth)
	// 생략
	return stack, backend
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;makeConfigNode&lt;/b&gt; 에서 Node를 만들어주고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;utils.RegisterEthService&lt;/b&gt; 에서 backend를 만들어준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 함수들을 하나씩 살펴보자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;makeConfigNode&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;geth 설정을 불러오고 빈 노드를 만들어주는 함수다.&lt;/p&gt;
&lt;pre id=&quot;code_1707397431771&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// makeConfigNode loads geth configuration and creates a blank node instance.
func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) {
	cfg := loadBaseConfig(ctx)
	stack, err := node.New(&amp;amp;cfg.Node)
	if err != nil {
		utils.Fatalf(&quot;Failed to create the protocol stack: %v&quot;, err)
	}
	// Node doesn't by default populate account manager backends
	if err := setAccountManagerBackends(stack.Config(), stack.AccountManager(), stack.KeyStoreDir()); err != nil {
		utils.Fatalf(&quot;Failed to set account manager backends: %v&quot;, err)
	}

	utils.SetEthConfig(ctx, stack, &amp;amp;cfg.Eth)
	if ctx.IsSet(utils.EthStatsURLFlag.Name) {
		cfg.Ethstats.URL = ctx.String(utils.EthStatsURLFlag.Name)
	}
	applyMetricConfig(ctx, &amp;amp;cfg)

	return stack, cfg
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;loadBaseConfig(ctx)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커맨드라인 파라미터들과 config 파일을 읽어서 gethConfig를 리턴해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1707398096969&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// loadBaseConfig loads the gethConfig based on the given command line
// parameters and config file.
func loadBaseConfig(ctx *cli.Context) gethConfig {}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gethConfig 타입은 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gethConfig에 대해 조금 말을 붙이자면, 우리가 보고 있는 것은 geth 클라이언트이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;geth 아래에 node와 eth가 있으니 gethConfig 타입을 통해 해당 설정들을 한 번에 관리해주는 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1707398408341&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;type gethConfig struct {
	Eth      ethconfig.Config
	Node     node.Config
	Ethstats ethstatsConfig
	Metrics  metrics.Config
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 함수를 보자면 default 설정을 불러와 주고, 설정파일에 있는 설정을 불러와준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이러한 설정을 가지고 node만의 설정을 해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1709640284961&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func loadBaseConfig(ctx *cli.Context) gethConfig {
	// Load defaults.
	cfg := gethConfig{
		Eth:     ethconfig.Defaults,
		Node:    defaultNodeConfig(),
		Metrics: metrics.DefaultConfig,
	}

	// Load config file.
	if file := ctx.String(configFileFlag.Name); file != &quot;&quot; {
		if err := loadConfig(file, &amp;amp;cfg); err != nil {
			utils.Fatalf(&quot;%v&quot;, err)
		}
	}

	// Apply flags.
	utils.SetNodeConfig(ctx, &amp;amp;cfg.Node)
	return cfg
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;노드만의 설정이란..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;node.Node 타입의 config를 설정해주는 것인데 파라미터로 context와 config 포인터를 받음을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;context에는 우리가 geth 실행할 때 넣어준 인자들이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 인자를 통해 적절한 설정을 해주는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SetNodeConfig 함수를 보자면 아래와 같이 node.Config를 설정해준다 라고 보면된다.&lt;/p&gt;
&lt;pre id=&quot;code_1709640469393&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// SetNodeConfig applies node-related command line flags to the config.
func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
	SetP2PConfig(ctx, &amp;amp;cfg.P2P)
	setIPC(ctx, cfg)
	setHTTP(ctx, cfg)
	setGraphQL(ctx, cfg)
	setWS(ctx, cfg)
	setNodeUserIdent(ctx, cfg)
	SetDataDir(ctx, cfg)
	setSmartCard(ctx, cfg)

	if ctx.IsSet(JWTSecretFlag.Name) {
		cfg.JWTSecret = ctx.String(JWTSecretFlag.Name)
	}
    
    .. 생략&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;node.New()&lt;/h3&gt;
&lt;pre id=&quot;code_1707407518525&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cfg := loadBaseConfig(ctx)
stack, err := node.New(&amp;amp;cfg.Node)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;loadBaseConfig() 함수를 통해 노드의 기본 설정을 세팅해줬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정을 세팅했으니 이제 설정을 바탕으로 노드를 만드는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;node.New() 함수를 통해 P2P 노드를 만들어준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;New() 함수는 꽤나 길다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 노드를 만든다는 함수라 재밌을 것 같아서 다 가져왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체적인 내용은&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 노드에 대한 기본 설정을 가지고 와서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.&amp;nbsp; node := &amp;amp;Node{}를 통해 새로운 노드를 만들어서&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 노드의 멤버변수(server, config 등등)들을 설정해주고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 중간중간 문제되지 않게 에러처리 해주고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 그 노드를 반환해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서는 정도로만 이해하면 좋을 것 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1707407967608&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// New creates a new P2P node, ready for protocol registration.
func New(conf *Config) (*Node, error) {
	// Copy config and resolve the datadir so future changes to the current
	// working directory don't affect the node.
	confCopy := *conf
	conf = &amp;amp;confCopy
	if conf.DataDir != &quot;&quot; {
		absdatadir, err := filepath.Abs(conf.DataDir)
		if err != nil {
			return nil, err
		}
		conf.DataDir = absdatadir
	}
	if conf.Logger == nil {
		conf.Logger = log.New()
	}

	// Ensure that the instance name doesn't cause weird conflicts with
	// other files in the data directory.
	if strings.ContainsAny(conf.Name, `/\`) {
		return nil, errors.New(`Config.Name must not contain '/' or '\'`)
	}
	if conf.Name == datadirDefaultKeyStore {
		return nil, errors.New(`Config.Name cannot be &quot;` + datadirDefaultKeyStore + `&quot;`)
	}
	if strings.HasSuffix(conf.Name, &quot;.ipc&quot;) {
		return nil, errors.New(`Config.Name cannot end in &quot;.ipc&quot;`)
	}
	server := rpc.NewServer()
	server.SetBatchLimits(conf.BatchRequestLimit, conf.BatchResponseMaxSize)
	node := &amp;amp;Node{
		config:        conf,
		inprocHandler: server,
		eventmux:      new(event.TypeMux),
		log:           conf.Logger,
		stop:          make(chan struct{}),
		server:        &amp;amp;p2p.Server{Config: conf.P2P},
		databases:     make(map[*closeTrackingDB]struct{}),
	}

	// Register built-in APIs.
	node.rpcAPIs = append(node.rpcAPIs, node.apis()...)

	// Acquire the instance directory lock.
	if err := node.openDataDir(); err != nil {
		return nil, err
	}
	keyDir, isEphem, err := conf.GetKeyStoreDir()
	if err != nil {
		return nil, err
	}
	node.keyDir = keyDir
	node.keyDirTemp = isEphem
	// Creates an empty AccountManager with no backends. Callers (e.g. cmd/geth)
	// are required to add the backends later on.
	node.accman = accounts.NewManager(&amp;amp;accounts.Config{InsecureUnlockAllowed: conf.InsecureUnlockAllowed})

	// Initialize the p2p server. This creates the node key and discovery databases.
	node.server.Config.PrivateKey = node.config.NodeKey()
	node.server.Config.Name = node.config.NodeName()
	node.server.Config.Logger = node.log
	node.config.checkLegacyFiles()
	if node.server.Config.NodeDatabase == &quot;&quot; {
		node.server.Config.NodeDatabase = node.config.NodeDB()
	}

	// Check HTTP/WS prefixes are valid.
	if err := validatePrefix(&quot;HTTP&quot;, conf.HTTPPathPrefix); err != nil {
		return nil, err
	}
	if err := validatePrefix(&quot;WebSocket&quot;, conf.WSPathPrefix); err != nil {
		return nil, err
	}

	// Configure RPC servers.
	node.http = newHTTPServer(node.log, conf.HTTPTimeouts)
	node.httpAuth = newHTTPServer(node.log, conf.HTTPTimeouts)
	node.ws = newHTTPServer(node.log, rpc.DefaultHTTPTimeouts)
	node.wsAuth = newHTTPServer(node.log, rpc.DefaultHTTPTimeouts)
	node.ipc = newIPCServer(node.log, conf.IPCEndpoint())

	return node, nil
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;utils.SetEthConfig()&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 eth 에 대한 설정을 해주는 함수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 왜 makeConfigNode 함수 안에 있는지는 아직 의문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜냐면 gethconfig에 node에 대한 config와 eth에 대한 config에 대한 변수가 각각 있는 것처럼&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;node와 eth는 약간 다르다고 볼 수 있다고 생각하기 때문이다,,&lt;/p&gt;
&lt;pre id=&quot;code_1707768048382&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// SetEthConfig applies eth-related command line flags to the config.
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;eth 관련 커맨드 라인 flag를 config에 넣어준다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여하튼 함수를 보자면 SetNodeConfig와 비슷하게 context를 가지고 ethconfig를 설정해준다고 보면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;node.Node를 인자로 받는 이유는 node와 eth가 공유하는 부분이 있기 때문이다.&lt;/p&gt;
&lt;pre id=&quot;code_1709641735712&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// SetEthConfig applies eth-related command line flags to the config.
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
	// Avoid conflicting network flags
	CheckExclusive(ctx, MainnetFlag, DeveloperFlag, GoerliFlag, SepoliaFlag, HoleskyFlag)
	CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer

	// Set configurations from CLI flags
	setEtherbase(ctx, cfg)
	setGPO(ctx, &amp;amp;cfg.GPO)
	setTxPool(ctx, &amp;amp;cfg.TxPool)
	setMiner(ctx, &amp;amp;cfg.Miner)
	setRequiredBlocks(ctx, cfg)
	setLes(ctx, cfg)

	// Cap the cache allowance and tune the garbage collector
	mem, err := gopsutil.VirtualMemory()
	if err == nil {
		if 32&amp;lt;&amp;lt;(^uintptr(0)&amp;gt;&amp;gt;63) == 32 &amp;amp;&amp;amp; mem.Total &amp;gt; 2*1024*1024*1024 {
			log.Warn(&quot;Lowering memory allowance on 32bit arch&quot;, &quot;available&quot;, mem.Total/1024/1024, &quot;addressable&quot;, 2*1024)
			mem.Total = 2 * 1024 * 1024 * 1024
		}
		allowance := int(mem.Total / 1024 / 1024 / 3)
		if cache := ctx.Int(CacheFlag.Name); cache &amp;gt; allowance {
			log.Warn(&quot;Sanitizing cache to Go's GC limits&quot;, &quot;provided&quot;, cache, &quot;updated&quot;, allowance)
			ctx.Set(CacheFlag.Name, strconv.Itoa(allowance))
		}
	}
    
    ... 생략&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;applyMetricConfig()&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;setMetricConfig 라고 보면된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SetNodeConfig, SetEthconfig와 비슷하게 컨텍스트를 기반으로 metric에 관한 설정을 해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1707768003655&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if ctx.IsSet(utils.MetricsEnabledFlag.Name) {
    cfg.Metrics.Enabled = ctx.Bool(utils.MetricsEnabledFlag.Name)
}
if ctx.IsSet(utils.MetricsEnabledExpensiveFlag.Name) {
    cfg.Metrics.EnabledExpensive = ctx.Bool(utils.MetricsEnabledExpensiveFlag.Name)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 식으로 flag를 확인해서 ethconfig에 넣어준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 이름에서 보듯이 metric 관련 flag 일 것이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;makeConfigNode() 정리&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;makeConfigNode는 geth 설정을 불러오고 빈 노드를 만들어주는 함수, 노드와 gethConfig를 반환한다.&lt;br /&gt;&lt;br /&gt;loadBaseConfig를 통해 가져온 기본 설정을 이용하여 노드를 생성&lt;br /&gt;ethConfig와 metricConfig 적용 후 노드와 config 리턴해준다.&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;기타&lt;/h2&gt;
&lt;pre id=&quot;code_1707768566744&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if ctx.IsSet(utils.OverrideCancun.Name) {
    v := ctx.Uint64(utils.OverrideCancun.Name)
    cfg.Eth.OverrideCancun = &amp;amp;v
}
if ctx.IsSet(utils.OverrideVerkle.Name) {
    v := ctx.Uint64(utils.OverrideVerkle.Name)
    cfg.Eth.OverrideVerkle = &amp;amp;v
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1707768911955&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Create gauge with geth system and build information
if eth != nil { // The 'eth' backend may be nil in light mode
    var protos []string
    for _, p := range eth.Protocols() {
        protos = append(protos, fmt.Sprintf(&quot;%v/%d&quot;, p.Name, p.Version))
    }
    metrics.NewRegisteredGaugeInfo(&quot;geth/info&quot;, nil).Update(metrics.GaugeInfoValue{
        &quot;arch&quot;:      runtime.GOARCH,
        &quot;os&quot;:        runtime.GOOS,
        &quot;version&quot;:   cfg.Node.Version,
        &quot;protocols&quot;: strings.Join(protos, &quot;,&quot;),
    })
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;정리&lt;/h2&gt;</description>
      <category>blockchain/geth 소스코드 분석</category>
      <author>uzzam</author>
      <guid isPermaLink="true">https://uzzam.tistory.com/59</guid>
      <comments>https://uzzam.tistory.com/59#entry59comment</comments>
      <pubDate>Wed, 7 Feb 2024 20:19:25 +0900</pubDate>
    </item>
    <item>
      <title>파캐스터(Farcaster)를 알아보자</title>
      <link>https://uzzam.tistory.com/58</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;최근(2024년 2월 5일 기준) 가장 핫한 키워드라 하면 &quot;파캐스터&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 사람들이 하고 있는 앱이름은 &quot;Warpcast&quot; (워프캐스트)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 사람들이 파캐스터라고 할까보니 워프캐스트는 파캐스터의 클라이언트다..&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-02-05 오후 10.08.02.png&quot; data-origin-width=&quot;350&quot; data-origin-height=&quot;130&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lH0mO/btsEoLJ9mP2/2xpFxAhyiWo2LxietEvLWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lH0mO/btsEoLJ9mP2/2xpFxAhyiWo2LxietEvLWK/img.png&quot; data-alt=&quot;앱스토어에서 가져옴&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lH0mO/btsEoLJ9mP2/2xpFxAhyiWo2LxietEvLWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlH0mO%2FbtsEoLJ9mP2%2F2xpFxAhyiWo2LxietEvLWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;245&quot; height=&quot;91&quot; data-filename=&quot;스크린샷 2024-02-05 오후 10.08.02.png&quot; data-origin-width=&quot;350&quot; data-origin-height=&quot;130&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;앱스토어에서 가져옴&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Farcaster(파캐스터)가 뭘까?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.farcaster.xyz/apps&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.farcaster.xyz/apps&lt;/a&gt; -&amp;gt; 공홈&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.farcaster.xyz/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.farcaster.xyz/&lt;/a&gt; -&amp;gt; 공식 문서 참고해서 정리해보겠다..&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-02-05 오후 10.22.01.png&quot; data-origin-width=&quot;1252&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5LE9m/btsEmqmLpJ8/4WiCqeha0zKDV4aErtODw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5LE9m/btsEmqmLpJ8/4WiCqeha0zKDV4aErtODw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5LE9m/btsEmqmLpJ8/4WiCqeha0zKDV4aErtODw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5LE9m%2FbtsEmqmLpJ8%2F4WiCqeha0zKDV4aErtODw1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;615&quot; height=&quot;156&quot; data-filename=&quot;스크린샷 2024-02-05 오후 10.22.01.png&quot; data-origin-width=&quot;1252&quot; data-origin-height=&quot;318&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파캐스터는 &lt;b&gt;이더리움에 만들어진 탈중앙화된 소셜 네트워크&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고&lt;b&gt; 오픈소스 프로토콜&lt;/b&gt;이라 누구나 가져다가 데이터를 읽고 쓰는 앱을 만들면 된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;파캐스터 = 이더리움에 만들어진 탈중앙화된 소셜 네트워크이자 오픈소스 프로토콜&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자들은 그들의 계정을 갖고 있고, 다른 유저들과 상호작용하며 다른 앱으로 자유롭게 이동 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Accounts, Usernames, Message, Apps 4가지 개념이 있는데 자세히 살펴보자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Accounts&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파캐스터 계정은 username과 프로필 사진을 설정하고, casts라고 불리는 텍스트 메시지를 배포할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;casts == 트윗이라고 생각하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;온체인 트랜잭션 날려서 아무 이더리움 주소나 파캐스터에 등록 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;등록은?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IdGateway 컨트랙트를 호출하면서 계정이 생정된다. 이 과정에서 새로운 파캐스터 ID (fid)가 이더리움 주소에 할당된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계정을 사용하기 전에 username 설정, storage 렌트, 키 추가 과정을 거쳐야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 과정을 쉽게 해주는 Warpcast를 쓰자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Usernames&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;username은 @~~~ 로 되어 있는 아이디를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ENS를 사용해서 username 관리 해준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;username 변경도 가능하다. 너무 자주 바꾸면 계정에 대한 신뢰를 떨어트리니까 너무 자주 바꾸지는 말자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오프체인 - @alice (무료 및 파캐스터가 관리)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;온체인 - @alice.eth (유료 및 지갑이 관리)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Messages&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메시지는 이러한 다섯 개 타입으로 되어있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-02-06 오전 1.10.13.png&quot; data-origin-width=&quot;1198&quot; data-origin-height=&quot;1002&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eh0oxQ/btsEwJjVa7e/kKKccNeqjZsHLoivK2M3S0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eh0oxQ/btsEwJjVa7e/kKKccNeqjZsHLoivK2M3S0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eh0oxQ/btsEwJjVa7e/kKKccNeqjZsHLoivK2M3S0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Feh0oxQ%2FbtsEwJjVa7e%2FkKKccNeqjZsHLoivK2M3S0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;423&quot; height=&quot;354&quot; data-filename=&quot;스크린샷 2024-02-06 오전 1.10.13.png&quot; data-origin-width=&quot;1198&quot; data-origin-height=&quot;1002&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파캐스터 네트워크에 메시지를 유지하기 위해서는 storage를 빌려야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크를 스팸으로 채우는 것을 방지하는 것이다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 Warpcast에 가입하면 돈을 내야하는데 이것 때문인 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메시지 삭제는 삭제 메시지를 게시해서 삭제한다고 한다. 완전 삭제되는 건 아니고 tombstone을 남겨서 밀려나기 전까지 스토리지 한도에 포함된다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Apps&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;App에는 wallet App, Connected App 두 종류가 있는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Wallet App&lt;/b&gt; -서명하고, connected app 을 추가하고, 메시지를 포스팅하고 탐색할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; 메타마스크 같은 일반 지갑&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Connected App - &lt;/b&gt;메시지를 포스팅하고 탐색하는 것만 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; warpcast, supercast, yup 등등&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니까 warpcast앱과 이더리움 지갑이 있어야 쉽고, 온전하게 사용 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Frames&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프레임이 바로 사람들이 파캐스터를 찬양하는 이유이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐스트를 앱으로 만들어주기 때문이다,,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반 메시지를 상호작용 할 수 있게 하여 설문조사를 할 수도 있고 대화형으로 이어가게 할 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;아키텍처&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1736&quot; data-origin-height=&quot;1180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGtvQa/btsEvfDugls/vycnfOhUdiKIJ1seNfBVnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGtvQa/btsEvfDugls/vycnfOhUdiKIJ1seNfBVnk/img.png&quot; data-alt=&quot;https://docs.farcaster.xyz/learn/architecture/overview&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGtvQa/btsEvfDugls/vycnfOhUdiKIJ1seNfBVnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGtvQa%2FbtsEvfDugls%2FvycnfOhUdiKIJ1seNfBVnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;637&quot; height=&quot;433&quot; data-origin-width=&quot;1736&quot; data-origin-height=&quot;1180&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://docs.farcaster.xyz/learn/architecture/overview&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;identity는 온체인에, 데이터는 오프체인에 저장하는 하이브리드 아키텍처를 가지고 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;사용자 수 추이&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파캐스터가 최근에 생긴 앱은 아니고 꾸준히 개발되어 왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;dau는 근 일주일 ~ 며칠간 급상승했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-02-06 오전 2.19.29.png&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NLQBw/btsEonJI8zf/sutIzhkk8mbKEH724QEmSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NLQBw/btsEonJI8zf/sutIzhkk8mbKEH724QEmSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NLQBw/btsEonJI8zf/sutIzhkk8mbKEH724QEmSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNLQBw%2FbtsEonJI8zf%2FsutIzhkk8mbKEH724QEmSK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;515&quot; height=&quot;251&quot; data-filename=&quot;스크린샷 2024-02-06 오전 2.19.29.png&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;456&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;farcaster 듄 애널리틱스 : &lt;a href=&quot;https://dune.com/pixelhack/farcaster&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://dune.com/pixelhack/farcaster&lt;/a&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;Degen, Frame 에어드랍&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.degen.tips/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.degen.tips/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Degen, Frame 에어드랍이 핫했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2월말에 Degen은 에어드랍2가 있을 예정이어서 그걸 준비해보려는 사람들이 바글바글하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;개인적인 생각 및 분석&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 앱은 엄청 재밌는 건 아닌데 자꾸 켜게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보가 넘쳐 흐르고, 조회수를 위해 게시물을 퍼다나르는 사람들이 많아진 X가 좀 질리는 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;누군가는 매스어답션 말하지만 글쎄..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 느꼈을 때는 단지 에어드랍을 위해 몰려들어온 사람 + 진또배기 정도라고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파캐스터가 민팅(여러 기능) + 마케팅 + 커뮤니티의 합이라고 볼 수 있고 크립토 생태계에 최적이라해도 이건 단지 크립토에만 국한될 뿐&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블록체인 업계에 관심 없는 사람까지 끌어들일 원동력은 아직 없다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 계속 개발되고 하다보면 좋은 결과를 얻을 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당분간 사용자 수의 고점은 friend.tech이랑 비슷하지 않을까 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그거 했던 사람들이 또 여기와서 있겠지,,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>blockchain (리서치)</category>
      <author>uzzam</author>
      <guid isPermaLink="true">https://uzzam.tistory.com/58</guid>
      <comments>https://uzzam.tistory.com/58#entry58comment</comments>
      <pubDate>Tue, 6 Feb 2024 02:43:32 +0900</pubDate>
    </item>
    <item>
      <title>Geth 소스코드 분석 3 - 시작지점 살펴보기</title>
      <link>https://uzzam.tistory.com/57</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이제부터는 코드를 가져올 예정이기 때문에 글 하나하나가 굉장히 길 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 geth 클라이언트의 시작점은 대체 어디일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main.go 파일을 찾아야 하는데 다양한 패키지가 있고 많은 main.go가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;geth 클라이언트를 실행할 때 터미널에서 geth ~~~ 명령어를 입력하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것과 관련된 명령어를 치는 부분인 cmd/geth/main.go 가 바로 시작점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본격적인 흐름을 보기 전에 자주 나오는 타입에 대해서는 한 번 보고가는게 좋을 것 같다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;main()&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 시작 함수인 main()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 app.Run 을 실행하고, 에러가 있으면 에러 출력과 함께 종료한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때 app.Run의 argument인 os.Args 는 geth 명령어를 입력할 때 들어오는 값이다.&lt;/p&gt;
&lt;pre id=&quot;code_1706461099418&quot; class=&quot;stata&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;func main() {
	if err := app.Run(os.Args); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1706461115160&quot; class=&quot;vim&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;geth [global options] command [command options] [arguments...]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;geth 뒤에 있는 값들을 받아와서 그에 맞는 명령어를 실행시켜주는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;app&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 app은 뭐고 Run을 실행하면 어떤 일이 일어날까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;app은 아래의 변수 선언과 init() 함수를 통해 초기화를 해준다고 볼 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;app 변수 선언&lt;/h3&gt;
&lt;pre id=&quot;code_1706461122210&quot; class=&quot;stata&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var app = flags.NewApp(&quot;the go-ethereum command line interface&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;flags 패키지의 NewApp 함수(flags.newApp)는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1707305792313&quot; class=&quot;stata&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;// NewApp creates an app with sane defaults.
func NewApp(usage string) *cli.App {
	git, _ := version.VCS()
	app := cli.NewApp()
	app.EnableBashCompletion = true
	app.Version = params.VersionWithCommit(git.Commit, git.Date)
	app.Usage = usage
	app.Copyright = &quot;Copyright 2013-2024 The go-ethereum Authors&quot;
	app.Before = func(ctx *cli.Context) error {
		MigrateGlobalFlags(ctx)
		return nil
	}
	return app
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 이전 글에서 본 것 처럼 cli.NewApp을 통해 기본 App을 만들어주는 것을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 기본 설정을 App에 넣어준 후 반환해준다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;init()&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;init 함수는 프로그램이 시작될 때 자동으로 호출된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cli.App타입인 app이라는 이름을 가진 변수에 &lt;b&gt;action, commands, flags, before, after&lt;/b&gt; 넣어줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각의 특성이 뭘하는지 이전 글에서 확인할 수 있었다.&lt;/p&gt;
&lt;pre id=&quot;code_1706461122210&quot; class=&quot;go&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;func init() {
	// Initialize the CLI app and start Geth
	app.Action = geth
	app.Commands = []*cli.Command{
		// See chaincmd.go:
		initCommand,
		importCommand,
		exportCommand,
		importPreimagesCommand,
		removedbCommand,
		dumpCommand,
		dumpGenesisCommand,
		// See accountcmd.go:
		accountCommand,
		walletCommand,
		// See consolecmd.go:
		consoleCommand,
		attachCommand,
		javascriptCommand,
		// See misccmd.go:
		versionCommand,
		versionCheckCommand,
		licenseCommand,
		// See config.go
		dumpConfigCommand,
		// see dbcmd.go
		dbCommand,
		// See cmd/utils/flags_legacy.go
		utils.ShowDeprecated,
		// See snapshot.go
		snapshotCommand,
		// See verkle.go
		verkleCommand,
	}
	if logTestCommand != nil {
		app.Commands = append(app.Commands, logTestCommand)
	}
	sort.Sort(cli.CommandsByName(app.Commands))

	app.Flags = flags.Merge(
		nodeFlags,
		rpcFlags,
		consoleFlags,
		debug.Flags,
		metricsFlags,
	)
	flags.AutoEnvVars(app.Flags, &quot;GETH&quot;)

	app.Before = func(ctx *cli.Context) error {
		maxprocs.Set() // Automatically set GOMAXPROCS to match Linux container CPU quota.
		flags.MigrateGlobalFlags(ctx)
		if err := debug.Setup(ctx); err != nil {
			return err
		}
		flags.CheckEnvVars(ctx, app.Flags, &quot;GETH&quot;)
		return nil
	}
	app.After = func(ctx *cli.Context) error {
		debug.Exit()
		prompt.Stdin.Close() // Resets terminal mode.
		return nil
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지 하면 app에 대한 정보가 들어갔다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;app.Run&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 다시 메인함수에 있었던 app.Run으로 돌아가보자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;app.Run은 &lt;b&gt;Run -&amp;gt; RunContext&lt;/b&gt; 함수를 실행하고 에러를 반환해준다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Run()&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Run() 함수는 단순히 RunContext 함수를 실행시켜준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;context.Background() 는 빈 context.Context 를 만들어주는 함수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빈 Context와 실행시에 받았던 arguments 들로 RunContext 함수를 실행하는 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1706461122212&quot; class=&quot;go&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;// Run is the entry point to the cli app. Parses the arguments slice and routes
// to the proper flag/args combination
func (a *App) Run(arguments []string) (err error) {
	return a.RunContext(context.Background(), arguments)
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;RunContext()&lt;/h3&gt;
&lt;pre id=&quot;code_1706461122212&quot; class=&quot;stylus&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;// RunContext is like Run except it takes a Context that will be
// passed to its commands and sub-commands. Through this, you can
// propagate timeouts and cancellation requests
func (a *App) RunContext(ctx context.Context, arguments []string) (err error) {
	a.Setup()

	// handle the completion flag separately from the flagset since
	// completion could be attempted after a flag, but before its value was put
	// on the command line. this causes the flagset to interpret the completion
	// flag name as the value of the flag before it which is undesirable
	// note that we can only do this because the shell autocomplete function
	// always appends the completion flag at the end of the command
	shellComplete, arguments := checkShellCompleteFlag(a, arguments)

	cCtx := NewContext(a, nil, &amp;amp;Context{Context: ctx})
	cCtx.shellComplete = shellComplete

	a.rootCommand = a.newRootCommand()
	cCtx.Command = a.rootCommand

	return a.rootCommand.Run(cCtx, arguments...)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;app을 Setup 해주는 것부터 시작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Setup 함수는 중요도에 비해 코드가 길어서 주석만 첨부했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Run 하기전에 필요한 설정들을 넣어준다고 생각하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1707392187276&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Setup runs initialization code to ensure all data structures are ready for
// `Run` or inspection prior to `Run`.  It is internally called by `Run`, but
// will return early if setup has already happened.
func (a *App) Setup() {}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음은 rootCommand 를 설정해주고 실행해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1707392428745&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a.rootCommand = a.newRootCommand()
cCtx.Command = a.rootCommand

return a.rootCommand.Run(cCtx, arguments...)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;a.rootCommand.Run() 함수는 상당히 긴데 맨 마지막 부분에 보면 이런 코드가 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1707392533780&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;err = c.Action(cCtx)

cCtx.App.handleExitCoder(cCtx, err)
return err&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Command 타입의 Action 에 정의해놨던 함수를 실행시켜주는 것이다..!!&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;geth()&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 init 함수에서 cli.App 의 Action을 app.Action = geth과 같이 정의해주었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 Run을 하게 되면 Action 함수를 실행하는 것을 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이 Action 함수에 해당하는 &lt;b&gt;geth&lt;/b&gt; 함수를 알아보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;geth에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;prepare, makeFullNode, startNode&lt;/b&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;세 가지 함수를 실행시켜 주는 것을 볼 수 있다!&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;이번 글에서는 makeFullNode와 startNode 함수를 제외한 나머지 부분을 살펴볼 예정이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1707392742419&quot; class=&quot;stata&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// geth is the main entry point into the system if no special subcommand is run.
// It creates a default node based on the command line arguments and runs it in
// blocking mode, waiting for it to be shut down.
func geth(ctx *cli.Context) error {
	if args := ctx.Args().Slice(); len(args) &amp;gt; 0 {
		return fmt.Errorf(&quot;invalid command: %q&quot;, args[0])
	}

	prepare(ctx)
	stack, backend := makeFullNode(ctx)
	defer stack.Close()

	startNode(ctx, stack, backend, false)
	stack.Wait()
	return nil
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상단의 if문은 커맨드가 잘못 입력되었을 때 에러를 반환해준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-27 오전 3.38.55.png&quot; data-origin-width=&quot;706&quot; data-origin-height=&quot;98&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/be0dZv/btsD2tJ49ol/ph21B2FQIy40K0gFKFVMbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/be0dZv/btsD2tJ49ol/ph21B2FQIy40K0gFKFVMbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/be0dZv/btsD2tJ49ol/ph21B2FQIy40K0gFKFVMbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbe0dZv%2FbtsD2tJ49ol%2Fph21B2FQIy40K0gFKFVMbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;706&quot; height=&quot;98&quot; data-filename=&quot;스크린샷 2024-01-27 오전 3.38.55.png&quot; data-origin-width=&quot;706&quot; data-origin-height=&quot;98&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 커맨드를 잘못 입력하면 해당 코드가 실행되는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;prepare()&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;prepare 함수는 flag에 따른 로그를 보여주고, metric 수집을 시작한다.&lt;/p&gt;
&lt;pre id=&quot;code_1707393631737&quot; class=&quot;go&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// prepare manipulates memory cache allowance and setups metric system.
// This function should be called before launching devp2p stack.
func prepare(ctx *cli.Context) {
	// If we're running a known preset, log it for convenience.
	switch {
	case ctx.IsSet(utils.GoerliFlag.Name):
		log.Info(&quot;Starting Geth on G&amp;ouml;rli testnet...&quot;)

	case ctx.IsSet(utils.SepoliaFlag.Name):
		log.Info(&quot;Starting Geth on Sepolia testnet...&quot;)

	case ctx.IsSet(utils.HoleskyFlag.Name):
		log.Info(&quot;Starting Geth on Holesky testnet...&quot;)

	case ctx.IsSet(utils.DeveloperFlag.Name):
		log.Info(&quot;Starting Geth in ephemeral dev mode...&quot;)
		log.Warn(`You are running Geth in --dev mode. Please note the following:

  1. This mode is only intended for fast, iterative development without assumptions on
     security or persistence.
  2. The database is created in memory unless specified otherwise. Therefore, shutting down
     your computer or losing power will wipe your entire block data and chain state for
     your dev environment.
  3. A random, pre-allocated developer account will be available and unlocked as
     eth.coinbase, which can be used for testing. The random dev account is temporary,
     stored on a ramdisk, and will be lost if your machine is restarted.
  4. Mining is enabled by default. However, the client will only seal blocks if transactions
     are pending in the mempool. The miner's minimum accepted gas price is 1.
  5. Networking is disabled; there is no listen-address, the maximum number of peers is set
     to 0, and discovery is disabled.
`)

	case !ctx.IsSet(utils.NetworkIdFlag.Name):
		log.Info(&quot;Starting Geth on Ethereum mainnet...&quot;)
	}
	// If we're a full node on mainnet without --cache specified, bump default cache allowance
	if !ctx.IsSet(utils.CacheFlag.Name) &amp;amp;&amp;amp; !ctx.IsSet(utils.NetworkIdFlag.Name) {
		// Make sure we're not on any supported preconfigured testnet either
		if !ctx.IsSet(utils.HoleskyFlag.Name) &amp;amp;&amp;amp;
			!ctx.IsSet(utils.SepoliaFlag.Name) &amp;amp;&amp;amp;
			!ctx.IsSet(utils.GoerliFlag.Name) &amp;amp;&amp;amp;
			!ctx.IsSet(utils.DeveloperFlag.Name) {
			// Nope, we're really on mainnet. Bump that cache up!
			log.Info(&quot;Bumping default cache on mainnet&quot;, &quot;provided&quot;, ctx.Int(utils.CacheFlag.Name), &quot;updated&quot;, 4096)
			ctx.Set(utils.CacheFlag.Name, strconv.Itoa(4096))
		}
	}

	// Start metrics export if enabled
	utils.SetupMetrics(ctx)

	// Start system runtime metrics collection
	go metrics.CollectProcessMetrics(3 * time.Second)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;metrics.CollectProcessMetrics()에서 &lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;처음으로 고루틴이 나온다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CollectProcessMetrics 함수를 살펴보면 3초에 한 번씩 sleep을 걸어주며 for문을 돌며 수집해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3초마다 정보를 수집해주는 경량 스레드가 처음으로 생성되었다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;stack.Close() , stack.Wait()&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;stack은 node.Node 타입인데, makeFullNode를 통해 받은 node를 wait 하다가 종료되면 close 해주는 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1706461122216&quot; class=&quot;go&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;// Close stops the Node and releases resources acquired in
// Node constructor New.
func (n *Node) Close() error {
	n.startStopLock.Lock()
	defer n.startStopLock.Unlock()

	n.lock.Lock()
	state := n.state
	n.lock.Unlock()
	switch state {
	case initializingState:
		// The node was never started.
		return n.doClose(nil)
	case runningState:
		// The node was started, release resources acquired by Start().
		var errs []error
		if err := n.stopServices(n.lifecycles); err != nil {
			errs = append(errs, err)
		}
		return n.doClose(errs)
	case closedState:
		return ErrNodeStopped
	default:
		panic(fmt.Sprintf(&quot;node is in unknown state %d&quot;, state))
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1706461122217&quot; class=&quot;crmsh&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;// Wait blocks until the node is closed.
func (n *Node) Wait() {
	&amp;lt;-n.stop
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;정리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서 본 건 geth cli app이 어떻게 켜지고 있는지 보았다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;geth 클라이언트가 실행될 때 cli.App 타입 변수인 app에 정보를 넣어주고 app.Run 함수를 통해 app.Action에 해당하는 함수인 geth 함수를 실행시켜주는 것이 전부이다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다음 글에서는 makeFullNode 함수를 알아보며 node를 어떻게 만드는지 알아보고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음 글에서 startNode 함수를 통해 node가 시작되는 과정을 살펴보겠다.&lt;/p&gt;</description>
      <category>blockchain/geth 소스코드 분석</category>
      <category>geth</category>
      <category>geth 분석</category>
      <category>go-ethereum</category>
      <category>이더리움</category>
      <author>uzzam</author>
      <guid isPermaLink="true">https://uzzam.tistory.com/57</guid>
      <comments>https://uzzam.tistory.com/57#entry57comment</comments>
      <pubDate>Tue, 30 Jan 2024 00:10:49 +0900</pubDate>
    </item>
    <item>
      <title>Geth 소스코드 분석 2 - 몇 가지 타입 살펴보기</title>
      <link>https://uzzam.tistory.com/56</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;지난 글에서 geth 클라이언트를 실행할 때 어떤 일이 일어나는지, 시작점부터 실행 순서대로 보도록 하겠다고 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 코드를 살펴본 결과 들어가기에 앞서 geth에서 사용하는 몇 가지 타입에 대해 살펴보면 이해가 더 쉬울 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글 부터는 이해를 위해 필요한 코드가 있으면 전부 가져올 예정이라 앞으로의 글들은 좀 길 예정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cli 패키지를 살짝 알아보고 아래 4가지 타입을 먼저 확인해보도록 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- cli 패키지의 App, Context&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Node 패키지의 node&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ethapi 패키지의 Backend&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;cli 패키지&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;import 문을 보면 &lt;a href=&quot;https://github.com/urfave/cli/v2&quot;&gt;https://github.com/urfave/cli/v2&lt;/a&gt;&amp;nbsp;에서 가져온 것을 확인할 수 있는데,,&lt;/p&gt;
&lt;pre id=&quot;code_1706352394145&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# https://cli.urfave.org/
urfave/cli is a simple, fast, and fun package for building command line apps in Go&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Go에서 command line app을 만드는 가볍고 빠르고 재밌는 패키지라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스타 수가 2만개가 넘긴 하지만, 월드 컴퓨터인 이더리움이 외부 패키지에 의존하고 있다니 보안적으로 취약한 거 아닌가 싶다가서도 모든 기능을 자체적으로 구현할 수는 없지 싶었다.&lt;/p&gt;
&lt;pre id=&quot;code_1706352572996&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// https://cli.urfave.org/v2/getting-started/

package main

import (
    &quot;fmt&quot;
    &quot;log&quot;
    &quot;os&quot;

    &quot;github.com/urfave/cli/v2&quot;
)

func main() {
    app := &amp;amp;cli.App{
        Name:  &quot;boom&quot;,
        Usage: &quot;make an explosive entrance&quot;,
        Action: func(*cli.Context) error {
            fmt.Println(&quot;boom! I say!&quot;)
            return nil
        },
    }

    if err := app.Run(os.Args); err != nil {
        log.Fatal(err)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 패키지에서 지원하는 docs에서 가져온 예시로 이런 형태로 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 형태는 후에 이더리움 앱의 시작점에서도 볼 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;cli.App&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;App이라는 타입은 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1706353236124&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// App is the main structure of a cli application. It is recommended that
// an app be created with the cli.NewApp() function
type App struct {
	// The name of the program. Defaults to path.Base(os.Args[0])
	Name string
	// Full name of command for help, defaults to Name
	HelpName string
	// Description of the program.
	Usage string
	// Text to override the USAGE section of help
	UsageText string
	// Description of the program argument format.
	ArgsUsage string
	// Version of the program
	Version string
	// Description of the program
	Description string
	// DefaultCommand is the (optional) name of a command
	// to run if no command names are passed as CLI arguments.
	DefaultCommand string
	// List of commands to execute
	Commands []*Command
	// List of flags to parse
	Flags []Flag
	// Boolean to enable bash completion commands
	EnableBashCompletion bool
	// Boolean to hide built-in help command and help flag
	HideHelp bool
	// Boolean to hide built-in help command but keep help flag.
	// Ignored if HideHelp is true.
	HideHelpCommand bool
	// Boolean to hide built-in version flag and the VERSION section of help
	HideVersion bool
	// categories contains the categorized commands and is populated on app startup
	categories CommandCategories
	// flagCategories contains the categorized flags and is populated on app startup
	flagCategories FlagCategories
	// An action to execute when the shell completion flag is set
	BashComplete BashCompleteFunc
	// An action to execute before any subcommands are run, but after the context is ready
	// If a non-nil error is returned, no subcommands are run
	Before BeforeFunc
	// An action to execute after any subcommands are run, but after the subcommand has finished
	// It is run even if Action() panics
	After AfterFunc
	// The action to execute when no subcommands are specified
	Action ActionFunc
	// Execute this function if the proper command cannot be found
	CommandNotFound CommandNotFoundFunc
	// Execute this function if a usage error occurs
	OnUsageError OnUsageErrorFunc
	// Execute this function when an invalid flag is accessed from the context
	InvalidFlagAccessHandler InvalidFlagAccessFunc
	// Compilation date
	Compiled time.Time
	// List of all authors who contributed
	Authors []*Author
	// Copyright of the binary if any
	Copyright string
	// Reader reader to write input to (useful for tests)
	Reader io.Reader
	// Writer writer to write output to
	Writer io.Writer
	// ErrWriter writes error output
	ErrWriter io.Writer
	// ExitErrHandler processes any error encountered while running an App before
	// it is returned to the caller. If no function is provided, HandleExitCoder
	// is used as the default behavior.
	ExitErrHandler ExitErrHandlerFunc
	// Other custom info
	Metadata map[string]interface{}
	// Carries a function which returns app specific info.
	ExtraInfo func() map[string]string
	// CustomAppHelpTemplate the text template for app help topic.
	// cli.go uses text/template to render templates. You can
	// render custom help text by setting this variable.
	CustomAppHelpTemplate string
	// SliceFlagSeparator is used to customize the separator for SliceFlag, the default is &quot;,&quot;
	SliceFlagSeparator string
	// DisableSliceFlagSeparator is used to disable SliceFlagSeparator, the default is false
	DisableSliceFlagSeparator bool
	// Boolean to enable short-option handling so user can combine several
	// single-character bool arguments into one
	// i.e. foobar -o -v -&amp;gt; foobar -ov
	UseShortOptionHandling bool
	// Enable suggestions for commands and flags
	Suggest bool
	// Allows global flags set by libraries which use flag.XXXVar(...) directly
	// to be parsed through this library
	AllowExtFlags bool
	// Treat all flags as normal arguments if true
	SkipFlagParsing bool

	didSetup  bool
	separator separatorSpec

	rootCommand *Command
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;App은 Cli 앱의 메인 구조로 cli.NewApp()을 통해 만들기를 권장한다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 후에 cli.NewApp()을 통해 App을 만들어주는 과정이 있을 것이라고 추측해 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;App타입에는 다양한 필드들이 있는데 짚고 넘어가면 좋을 것은&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Commands, Flags, Action, Before, After 이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Commands []*Command&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Commands 필드는 Command 타입의 포인터로 구성된 슬라이스인데 Command 타입은 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Command 타입은 우리가 geth를 실행할 때 입력하는 명령어를 정의해 놓은 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1706463697095&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Command is a subcommand for a cli.App.
type Command struct {
	// The name of the command
	Name string
	// A list of aliases for the command
	Aliases []string
	// A short description of the usage of this command
	Usage string
	// Custom text to show on USAGE section of help
	UsageText string
	// A longer explanation of how the command works
	Description string
	// A short description of the arguments of this command
	ArgsUsage string
	// The category the command is part of
	Category string
	// The function to call when checking for bash command completions
	BashComplete BashCompleteFunc
	// An action to execute before any sub-subcommands are run, but after the context is ready
	// If a non-nil error is returned, no sub-subcommands are run
	Before BeforeFunc
	// An action to execute after any subcommands are run, but after the subcommand has finished
	// It is run even if Action() panics
	After AfterFunc
	// The function to call when this command is invoked
	Action ActionFunc
	// Execute this function if a usage error occurs.
	OnUsageError OnUsageErrorFunc
	// List of child commands
	Subcommands []*Command
	// List of flags to parse
	Flags          []Flag
	flagCategories FlagCategories
	// Treat all flags as normal arguments if true
	SkipFlagParsing bool
	// Boolean to hide built-in help command and help flag
	HideHelp bool
	// Boolean to hide built-in help command but keep help flag
	// Ignored if HideHelp is true.
	HideHelpCommand bool
	// Boolean to hide this command from help or completion
	Hidden bool
	// Boolean to enable short-option handling so user can combine several
	// single-character bool arguments into one
	// i.e. foobar -o -v -&amp;gt; foobar -ov
	UseShortOptionHandling bool

	// Full name of command for help, defaults to full command name, including parent commands.
	HelpName        string
	commandNamePath []string

	// CustomHelpTemplate the text template for the command help topic.
	// cli.go uses text/template to render templates. You can
	// render custom help text by setting this variable.
	CustomHelpTemplate string

	// categories contains the categorized commands and is populated on app startup
	categories CommandCategories

	// if this is a root &quot;special&quot; command
	isRoot bool

	separator separatorSpec
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 터미널 창에 geth 관련 명령어를 입력하면 아래와 같이 하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때 'COMMANDS'에 표시된 account 등등이 모두 Command 타입인 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 Command 타입에 Subcommands 라는 필드가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 ' geth account list' 같이 account 아래에도 하위 커맨드가 있는데 그것 또한 Command 타입으로 되어 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1706464323969&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;NAME:
   geth - the go-ethereum command line interface

USAGE:
   geth [global options] command [command options] [arguments...]

COMMANDS:
   account                Manage accounts
   attach                 Start an interactive JavaScript environment (connect to node)
   ...(생략)
   help, h                Shows a list of commands or help for one command

GLOBAL OPTIONS:
   ACCOUNT

    --allow-insecure-unlock        (default: false)
          Allow insecure account unlocking when account-related RPCs are exposed by http

    --keystore value
          Directory for the keystore (default = inside the datadir)
          
    (생략)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Flags []Flag&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;geth를 실행하면서 옵션이나 매개변수를 전달하게 되는데 이 때 쓰이는 것이 플래그다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 인터페이스가 있으며 패키지에서 기본적으로 제공하는 flag(stringflag, intflag, boolflag 등)도 있고 사용자 정의 flag를 만들어서 사용할 수도 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1706464562653&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Flag is a common interface related to parsing flags in cli.
// For more advanced flag parsing techniques, it is recommended that
// this interface be implemented.
type Flag interface {
	fmt.Stringer
	// Apply Flag settings to the given flag set
	Apply(*flag.FlagSet) error
	Names() []string
	IsSet() bool
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들자면 아래에서 GLOBAL OPTIONS 가 flag라고 보면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1706465690714&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;NAME:
   geth - the go-ethereum command line interface

USAGE:
   geth [global options] command [command options] [arguments...]

COMMANDS:
   ...(생략)

GLOBAL OPTIONS:
    (생략)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;global options (flag 타입) - cli의 flag&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;command (command타입) - cli의 command&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;subcommand (command 타입) - command 의 subcommand&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;command options (flag 타입) - command 의 flag&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 형태를 띄고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cmd/utils/flags.go 에서 현재 사용하는 모든 flag를 확인할 수 있고, DirectoryFlag가 있는데 이건 cli 패키지에서 제공하는 것이 아닌 직접 만든 것이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Action, Before, After&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Action 은 메인 액션을 정의해주고, before과 after는 메인 액션 혹은 서브커맨드 전 후로 실행되는 함수라고 생각하면 될 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한 부분은 Action이다. (Action == 메인)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Action ActionFunc&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1706466222289&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// ActionFunc is the action to execute when no subcommands are specified
type ActionFunc func(*Context) error&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Before BeforeFunc&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1706466204939&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// BeforeFunc is an action to execute before any subcommands are run, but after
// the context is ready if a non-nil error is returned, no subcommands are run
type BeforeFunc func(*Context) error&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;After AfterFunc&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1706466214006&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// AfterFunc is an action to execute after any subcommands are run, but after the
// subcommand has finished it is run even if Action() panics
type AfterFunc func(*Context) error&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;cli.Context&lt;/h2&gt;
&lt;pre id=&quot;code_1706460691305&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Context is a type that is passed through to
// each Handler action in a cli application. Context
// can be used to retrieve context-specific args and
// parsed command-line options.
type Context struct {
	context.Context
	App           *App
	Command       *Command
	shellComplete bool
	flagSet       *flag.FlagSet
	parentContext *Context
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;context 타입은 cli application에서 각 핸들러에 전달되는 타입으로 특정한 인자를 검색하거나 명령줄 옵션을 파싱하는데 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;App - 현재 실행 중인 앱에 대한 포인터&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Command - 현재 실행 중인 커맨드에 대한 포인터&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Context 는 아래와 같은 interface로 이루어져있다.&lt;/p&gt;
&lt;pre id=&quot;code_1707093120592&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 주석이 많아 주석 전부 제거

type Context interface {
	Deadline() (deadline time.Time, ok bool)
    
	Done() &amp;lt;-chan struct{}

	Err() error
    
	Value(key any) any
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 cli.Context의 경우 어떠한 실행이 있을 때 전달되는 것 정도로 이해하면 될 것 같다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;node.Node&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node는 서비스를 등록할 수 있는 컨테이너다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니까 흔히 우리가 얘기하는 노드,, 이더리움의 노드 그 자체인 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트 구독, 설정, 계정 관리, 로깅, 등등 다양한 기능과 노드에 대한 정보를 갖고 있다고 보면 될 것 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1706353339659&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Node is a container on which services can be registered.
type Node struct {
	eventmux      *event.TypeMux
	config        *Config
	accman        *accounts.Manager
	log           log.Logger
	keyDir        string        // key store directory
	keyDirTemp    bool          // If true, key directory will be removed by Stop
	dirLock       *flock.Flock  // prevents concurrent use of instance directory
	stop          chan struct{} // Channel to wait for termination notifications
	server        *p2p.Server   // Currently running P2P networking layer
	startStopLock sync.Mutex    // Start/Stop are protected by an additional lock
	state         int           // Tracks state of node lifecycle

	lock          sync.Mutex
	lifecycles    []Lifecycle // All registered backends, services, and auxiliary services that have a lifecycle
	rpcAPIs       []rpc.API   // List of APIs currently provided by the node
	http          *httpServer //
	ws            *httpServer //
	httpAuth      *httpServer //
	wsAuth        *httpServer //
	ipc           *ipcServer  // Stores information about the ipc http server
	inprocHandler *rpc.Server // In-process RPC request handler to process the API requests

	databases map[*closeTrackingDB]struct{} // All open databases
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;ethapi.Backend&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백엔드 타입은 api service 를 제공해주는 인터페이스라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백엔드라 하면 사용자가 직접적으로 보거나 상호작용하지 않는 서버, 애플리케이션, 데이터베이스 등의 시스템이라고 볼 수 있는데 그런 시스템과 상호작용할 수 있는 api에 대한 인터페이스라고 생각하면 될 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;backend는 블록체인의 데이터 관리, 네트워크 통신, 트랜잭션 처리 등 다양한 기능을 하는 부분이 담겨있다고 보면 될 것 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1706353366043&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Backend interface provides the common API services (that are provided by
// both full and light clients) with access to necessary functions.
type Backend interface {
	// General Ethereum API
	SyncProgress() ethereum.SyncProgress

	SuggestGasTipCap(ctx context.Context) (*big.Int, error)
	FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error)
	ChainDb() ethdb.Database
	AccountManager() *accounts.Manager
	ExtRPCEnabled() bool
	RPCGasCap() uint64            // global gas cap for eth_call over rpc: DoS protection
	RPCEVMTimeout() time.Duration // global timeout for eth_call over rpc: DoS protection
	RPCTxFeeCap() float64         // global tx fee cap for all transaction related APIs
	UnprotectedAllowed() bool     // allows only for EIP155 transactions.

	// Blockchain API
	SetHead(number uint64)
	HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error)
	HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error)
	HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error)
	CurrentHeader() *types.Header
	CurrentBlock() *types.Header
	BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error)
	BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error)
	BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error)
	StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error)
	StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error)
	PendingBlockAndReceipts() (*types.Block, types.Receipts)
	GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error)
	GetTd(ctx context.Context, hash common.Hash) *big.Int
	GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) *vm.EVM
	SubscribeChainEvent(ch chan&amp;lt;- core.ChainEvent) event.Subscription
	SubscribeChainHeadEvent(ch chan&amp;lt;- core.ChainHeadEvent) event.Subscription
	SubscribeChainSideEvent(ch chan&amp;lt;- core.ChainSideEvent) event.Subscription

	// Transaction pool API
	SendTx(ctx context.Context, signedTx *types.Transaction) error
	GetTransaction(ctx context.Context, txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64, error)
	GetPoolTransactions() (types.Transactions, error)
	GetPoolTransaction(txHash common.Hash) *types.Transaction
	GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error)
	Stats() (pending int, queued int)
	TxPoolContent() (map[common.Address][]*types.Transaction, map[common.Address][]*types.Transaction)
	TxPoolContentFrom(addr common.Address) ([]*types.Transaction, []*types.Transaction)
	SubscribeNewTxsEvent(chan&amp;lt;- core.NewTxsEvent) event.Subscription

	ChainConfig() *params.ChainConfig
	Engine() consensus.Engine

	// This is copied from filters.Backend
	// eth/filters needs to be initialized from this backend type, so methods needed by
	// it must also be included here.
	GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error)
	GetLogs(ctx context.Context, blockHash common.Hash, number uint64) ([][]*types.Log, error)
	SubscribeRemovedLogsEvent(ch chan&amp;lt;- core.RemovedLogsEvent) event.Subscription
	SubscribeLogsEvent(ch chan&amp;lt;- []*types.Log) event.Subscription
	SubscribePendingLogsEvent(ch chan&amp;lt;- []*types.Log) event.Subscription
	BloomStatus() (uint64, uint64)
	ServiceFilter(ctx context.Context, session *bloombits.MatcherSession)
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 정도만 알면 이러한 타입들을 볼 때 무슨 일을 하는 지 어렴풋이 알고 있기 때문에 geth가 처음 시작될 때 어떻게 되는지도 이해하기 훨씬 편하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후에 node.Node 타입은 stack이라는 이름으로 쓰이고 ethapi.Backend 타입은 backend 라는 이름으로 쓰이게 될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 다음 글에서는 진짜 geth의 시작점으로 가서 코드를 순차적으로 보도록 하겠다.&lt;/p&gt;</description>
      <category>blockchain/geth 소스코드 분석</category>
      <category>geth</category>
      <category>geth 분석</category>
      <category>go-ethereum</category>
      <category>이더리움</category>
      <author>uzzam</author>
      <guid isPermaLink="true">https://uzzam.tistory.com/56</guid>
      <comments>https://uzzam.tistory.com/56#entry56comment</comments>
      <pubDate>Mon, 29 Jan 2024 02:02:00 +0900</pubDate>
    </item>
    <item>
      <title>Geth 소스코드 분석 1 - 시작하기 및 전체 구조</title>
      <link>https://uzzam.tistory.com/55</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Geth 소스코드 분석을 해볼까 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Geth 소스코드를 분석한 한글 자료가 있긴 하지만 오래된 자료들이 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게다가 대부분의 자료가 중요한 업데이트 중 하나인 '더 머지' 업데이트 전 자료기 때문에 바뀐 점이 꽤나 많을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이더리움은 계속해서 업데이트 되기 때문에 그런 자료들을 참고해서 나도 한 번 코드를 살펴보려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아마 최신 자료가 별로 없는 건, 블록체인 업계에 신규 유입되는 개발자들이 많지 않고 또 과거에 비해 다양한 체인들이 많아져서 골고루 분포하기 때문이지 않을까 생각해본다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;좋은 자료 및 참고 자료&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/NAKsir-melody/go-ethereum-korean&quot;&gt;https://github.com/NAKsir-melody/go-ethereum-korean&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1kKwMyiuH_i4-2q1AihoRCxO3gfwMLIEL1E8tt5BjxnM/edit?usp=sharing&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.google.com/presentation/d/1kKwMyiuH_i4-2q1AihoRCxO3gfwMLIEL1E8tt5BjxnM/edit?usp=sharing&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 큰 도움이 된 두 자료.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;dsrv 김지윤 대표님이 작성하셨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Geth를 이해하는데 가장 큰 도움이 되는 자료이고 제일 많이 참고할 예정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://steemit.com/kr/@woojin.joe/go-ethereum-geth-day-01&quot;&gt;https://steemit.com/kr/@woojin.joe/go-ethereum-geth-day-01&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=4SOSY0gNy2g&quot;&gt;https://www.youtube.com/watch?v=4SOSY0gNy2g&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=4SOSY0gNy2g&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/dcFnTY/hyU8WosIPA/BDjRbeRkDRekUG7YJWZ221/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=648_178_788_330&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-original-url=&quot;&quot; data-video-title=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/4SOSY0gNy2g&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스팀잇 글과 유튜브가 한 세트라고 보면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스팀잇 글은 '자바 개발자의 go-ethereum(geth) 소스 분석기 시리즈로' 무려 6년 전 자료이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유튜브는 어쩌다가 찾게 되었는데 라인개발자 조우진님이 네이버? 라인?에서 강연하시는 영상이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Naver D2 채널에 올라와있다. 글과 같이 보면 더 이해가 쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Golang에 대한 부분도 알 수 있어서 좋았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/scalalang2/go-ethereum-code-analysis&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/scalalang2/go-ethereum-code-analysis&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비교적 최신 글로 (2년전)&lt;br /&gt;&lt;a href=&quot;https://github.com/agiletechvn/go-ethereum-code-analysis&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/agiletechvn/go-ethereum-code-analysis&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영문 버전의 자료 (6년전)를 한국어로 재해석했다고 되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체적인 폴더 구조를 살펴보며 전체적인 느낌을 잡고 geth를 실행하면 어떤 일이 일어나는지 순차적으로 보며 자세한 코드를 볼 예정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 보기 앞서 무슨 버전의 코드를 봐야 하나 싶었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최신 버전은 2일 전에 올라온 1.13.11인데 너무 최신이라 괜찮은가 싶어서 무슨 버전의 geth를 많이 사용하는지 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.ethernodes.org/client/geth&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.ethernodes.org/client/geth&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 주소에서 확인했는데 다들 비교적 최신 버전을 사용하고 있고, 1.13.11도 4%가 되기 때문에 1.13.11을 보기로 했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-27 오전 1.26.51.png&quot; data-origin-width=&quot;2208&quot; data-origin-height=&quot;1242&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MyIBq/btsD0HIPDhR/LEtbjMUQ58KXnxBNBRFlDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MyIBq/btsD0HIPDhR/LEtbjMUQ58KXnxBNBRFlDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MyIBq/btsD0HIPDhR/LEtbjMUQ58KXnxBNBRFlDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMyIBq%2FbtsD0HIPDhR%2FLEtbjMUQ58KXnxBNBRFlDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;860&quot; height=&quot;484&quot; data-filename=&quot;스크린샷 2024-01-27 오전 1.26.51.png&quot; data-origin-width=&quot;2208&quot; data-origin-height=&quot;1242&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 아래 명령어를 통해 1.13.11로 들어가서 보자&lt;/p&gt;
&lt;pre id=&quot;code_1706286826126&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git clone https://github.com/ethereum/go-ethereum.git
git checkout tags/v1.13.11&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;폴더 구조&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체적인 구조를 한 번 보면 도움이 될듯 말듯하다 ㅎㅎ (너무 방대하다)&lt;/p&gt;
&lt;pre id=&quot;code_1706288360240&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Package accounts implements high level Ethereum account management.
package accounts&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무슨 패키지인지 보통 이런식으로 주석이 달려있는 편인 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1706287072118&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// https://github.com/scalalang2/go-ethereum-code-analysis/blob/master/go-ethereum-code-analysis.md
// 에서 작성한 부분을 현재 geth v1.13.11 코드에 맞게 수정했다.
// contracts, les, light, mobile 삭제
// beacon, docs, internal, params, signer, swarm 추가
// cmd 하위 패키지 수정

accounts		이더리움 계정의 추상화된 코드를 제공함
beacon			beacon 체인과 관련 코드
build			스크립트(sh) 파일과 빌드에 관한 설정 파일들이 저장된 곳
cmd			다양한 CLI 명령어 도구
	/abidump	컨트랙트의 calldata 를 파싱해서 원본을 추출하는 도구
	/abigen		Solidity 소스 코드로부터 ABI파일을 만드는 명령어
    /bootnode	네트워크 디스커버리만을 위한 노드 실행
	/clef		노드의 운영과 개인키의 관리를 분리시키기 위해 사용되는 명령어
	/devp2p		devp2p(노드가 서로를 찾고 통신하는 방법을 정확하게 정의하는 이더리움 네트워크 프로토콜) 사양 구현
    /ethkey	ethkey is a simple command-line tool for working with Ethereum keyfiles.
	/evm		설정 가능하고 독립적으로 디버깅이 가능한 환경을 제공하는 이더리움 가상 머신 개발 도구
	/geth		이더리움 클라이언트 
	/p2psim		Http API를 시뮬레이션 하기 위한 명령어
	/rlpdump 	RLP 데이터의 형식화된 출력을 도와준다.
	/utils		유틸성 패키지
common			공통 도구를 제공한다.
consensus		ethash나 clique, ibft 같은 합의 엔진을 제공함
console			이더리움 콘솔 패키지
core			이더리움의 코어 데이터 구조체 혹은 알고리즘이 저장됨. (가상머신, 상태, 블록체인, 블룸필터 등)
crypto			암호화 &amp;amp; 해시 알고리즘
docs			audit 보고서랑, 버그 분석이 있음
eth				이더리움의 합의 구현체
ethclient		이더리움 RPC 클라이언트 코드
ethdb			이더리움 데이터베이스 (실제 저장소인 level-db와 테스트 용도인 in-memory 데이터베이스가 구현되어 있다.)
ethstats		네트워크 상태에 대한 정보를 제공한다.
event			실시간 이벤트 관리
graphql			GraphQL을 제공하는 도구
internal		내부적으로 쓰이는 것들?? 
log				로깅 패키지
metrics			그라파나 연동을 위한 메트릭을 제공한다.
miner			블록 생성 및 마이닝 기능을 제공한다.
node			다양한 타입의 이더리움 노드
p2p				p2p 네트워크 프로토콜
params			사전 정의된 상수 혹은 변수들이 있음
rlp				recursive length prefix의 약자로 이더리움에서 사용되는 직렬화 알고리즘
rpc				API와 서비스에서 사용되는 원격 함수 호출
signer			트랜잭션과 데이터의 서명 처리 관련
swarm			ethswarm.org 링크와 설명으로 이루어진 README.md 파일
tests			테스트 목적
trie			머클 패트리샤 트리의 구현체&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;아마 자세한 코드를 확인 후 다시 전체 구조를 바라보면 다른 느낌이 들 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;다음 글에서는 geth 클라이언트를 실행할 때 어떤 일이 일어나는지, 시작점부터 실행 순서대로 보도록 하겠다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>blockchain/geth 소스코드 분석</category>
      <category>geth</category>
      <category>geth 분석</category>
      <category>이더리움</category>
      <author>uzzam</author>
      <guid isPermaLink="true">https://uzzam.tistory.com/55</guid>
      <comments>https://uzzam.tistory.com/55#entry55comment</comments>
      <pubDate>Sat, 27 Jan 2024 01:49:15 +0900</pubDate>
    </item>
    <item>
      <title>Flutter 3.16을 올리고 UI 문제가 생겼다면</title>
      <link>https://uzzam.tistory.com/51</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Flutter 3.16을 올리고 UI 문제가 생겼다면 &lt;b&gt;material3 문제&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나도 flutter 3.16.x 버전으로 올리고 앱의 ui가 깨져보이기 시작했는데..&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_1324.PNG&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;190&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byJq4A/btsC4bpmqgr/Mmrn4zFLfTbm6qR1zBDIVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byJq4A/btsC4bpmqgr/Mmrn4zFLfTbm6qR1zBDIVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byJq4A/btsC4bpmqgr/Mmrn4zFLfTbm6qR1zBDIVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyJq4A%2FbtsC4bpmqgr%2FMmrn4zFLfTbm6qR1zBDIVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;403&quot; height=&quot;68&quot; data-filename=&quot;IMG_1324.PNG&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;190&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;3_16에러.png&quot; data-origin-width=&quot;314&quot; data-origin-height=&quot;50&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhl6Rj/btsCUyzEdId/ghzGisHh1wjdzjKA2zk0sk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhl6Rj/btsCUyzEdId/ghzGisHh1wjdzjKA2zk0sk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhl6Rj/btsCUyzEdId/ghzGisHh1wjdzjKA2zk0sk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbhl6Rj%2FbtsCUyzEdId%2FghzGisHh1wjdzjKA2zk0sk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;414&quot; height=&quot;66&quot; data-filename=&quot;3_16에러.png&quot; data-origin-width=&quot;314&quot; data-origin-height=&quot;50&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 처럼 보이던 탭바가 아래처럼 보이기 시작했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 밖에도 버튼 누를 때 애니메이션 같은게 조금 바뀌었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 그런가 찾아보니 flutter 3.16에서는 Material3가 기본이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://medium.com/flutter/whats-new-in-flutter-3-16-dba6cb1015d1&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://medium.com/flutter/whats-new-in-flutter-3-16-dba6cb1015d1&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704349831596&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;What&amp;rsquo;s new in Flutter 3.16&quot; data-og-description=&quot;Material 3 by default, Impeller preview for Android, DevTools extensions, and much more&quot; data-og-host=&quot;medium.com&quot; data-og-source-url=&quot;https://medium.com/flutter/whats-new-in-flutter-3-16-dba6cb1015d1&quot; data-og-url=&quot;https://medium.com/flutter/whats-new-in-flutter-3-16-dba6cb1015d1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bGcrhZ/hyUXUKCFIp/bkriW4wtQcURruS2Bld3Mk/img.png?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675&quot;&gt;&lt;a href=&quot;https://medium.com/flutter/whats-new-in-flutter-3-16-dba6cb1015d1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://medium.com/flutter/whats-new-in-flutter-3-16-dba6cb1015d1&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bGcrhZ/hyUXUKCFIp/bkriW4wtQcURruS2Bld3Mk/img.png?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;What&amp;rsquo;s new in Flutter 3.16&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Material 3 by default, Impeller preview for Android, DevTools extensions, and much more&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;medium.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이것과 관련해서 무엇을 적용해야 할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/flutter/flutter/issues/91605&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/flutter/flutter/issues/91605&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704349962508&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;☂️ Bring Material 3 to Flutter &amp;middot; Issue #91605 &amp;middot; flutter/flutter&quot; data-og-description=&quot;Material 3, also known as &amp;quot;Material You&amp;quot;, is the next generation of Material Design. The major changes include: updates to many components (colors, text styles and shapes, etc.) color system improv...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/flutter/flutter/issues/91605&quot; data-og-url=&quot;https://github.com/flutter/flutter/issues/91605&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/VFk5F/hyUXUX8ys5/OQbOQNBT5OknlAAq97Cxqk/img.png?width=1200&amp;amp;height=600&amp;amp;face=993_116_1051_179&quot;&gt;&lt;a href=&quot;https://github.com/flutter/flutter/issues/91605&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/flutter/flutter/issues/91605&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/VFk5F/hyUXUX8ys5/OQbOQNBT5OknlAAq97Cxqk/img.png?width=1200&amp;amp;height=600&amp;amp;face=993_116_1051_179');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;☂️ Bring Material 3 to Flutter &amp;middot; Issue #91605 &amp;middot; flutter/flutter&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Material 3, also known as &quot;Material You&quot;, is the next generation of Material Design. The major changes include: updates to many components (colors, text styles and shapes, etc.) color system improv...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;몇십 개가 되니 제대로 개발하려면 꼭 참고하는게 좋겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-01-04 오후 3.33.19.png&quot; data-origin-width=&quot;1366&quot; data-origin-height=&quot;1442&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2nbXA/btsC4rS65Om/dYagdNmRZKDixNKRE69Nc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2nbXA/btsC4rS65Om/dYagdNmRZKDixNKRE69Nc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2nbXA/btsC4rS65Om/dYagdNmRZKDixNKRE69Nc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2nbXA%2FbtsC4rS65Om%2FdYagdNmRZKDixNKRE69Nc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;705&quot; height=&quot;744&quot; data-filename=&quot;스크린샷 2024-01-04 오후 3.33.19.png&quot; data-origin-width=&quot;1366&quot; data-origin-height=&quot;1442&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아 umbrella issue라는 단어를 쓰길래 처음 들어봐서 뭔가 했더니 이렇다고 한다&lt;/p&gt;</description>
      <category>frameworks/flutter</category>
      <author>uzzam</author>
      <guid isPermaLink="true">https://uzzam.tistory.com/51</guid>
      <comments>https://uzzam.tistory.com/51#entry51comment</comments>
      <pubDate>Thu, 4 Jan 2024 15:35:42 +0900</pubDate>
    </item>
    <item>
      <title>src-20 민팅하기 및 뉴스들</title>
      <link>https://uzzam.tistory.com/49</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;067E9A7A-12C6-4FB1-952B-3389F93BD697.jpeg&quot; data-origin-width=&quot;828&quot; data-origin-height=&quot;826&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vi0YC/btsB19UXVkS/gT24AkAykgCPFDeR8Sqha0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vi0YC/btsB19UXVkS/gT24AkAykgCPFDeR8Sqha0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vi0YC/btsB19UXVkS/gT24AkAykgCPFDeR8Sqha0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fvi0YC%2FbtsB19UXVkS%2FgT24AkAykgCPFDeR8Sqha0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;189&quot; height=&quot;189&quot; data-filename=&quot;067E9A7A-12C6-4FB1-952B-3389F93BD697.jpeg&quot; data-origin-width=&quot;828&quot; data-origin-height=&quot;826&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Bonk 상장&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 핫한 뉴스는 bonk 상장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;12월 15일에 바이낸스에 상장되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bonk가 뭐냐 하면&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;Bonk is the first Solana dog coin for the people, by the people with 50% of the total supply airdropped to the Solana community. The Bonk contributors were tired of toxic &amp;ldquo;Alameda&amp;rdquo; tokenomics and wanted to make a fun memecoin where everyone gets a fair shot.&amp;nbsp; -coingecko&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;솔라나 밈코인이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인스크립션인 줄 알았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 인스크립션인 줄 알았냐면 지금 대세가 되고 있기 때문에,,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;대세가 되는 인스크립션&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근에 블록체인 팔로업을 다시 시작했기 때문에 아직 잘 모르는게 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쨌든 요즘에 인스크립션의 떡상으로 다른 체인들에서도 인스크립션을 넣는 시도가 많이 일어나고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감명깊은 문구가 있었는데&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;몇년 전 - bitcoin: when smartcontract?&lt;br /&gt;지금 - other chain : when inscription?&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요런거였는데 출처를 모르겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쨌든 인스크립션의 대세로 iost체인에서 인스크립션 민팅하다가 민팅을 멈췄다나 뭐라나 .. (확실치 않음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하여튼 대세가 되고 있긴 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;바이낸스 vs okx&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바이낸스가 얼마전에 1000sats 을 상장시킨 것도 그렇고 bonk 를 상장시킨 것도 그렇고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;brc-20으로 인해 okx에 빼앗긴 점유율을 가져오려는 것이다 라는 해석을 트위터 어디선가 봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하여튼 okx가 좀 더 brc-20에 진심인 듯 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;src-20 관련 뉴스들&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 뭐 요즘에는 src-20 정보를 위주로 보는 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;몇 가지 뉴스들이 있는데&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;src 인덱서 오픈소스 공개 예정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 알기론 지금 src-20 인덱서가 공개가 되지 않아서 openstamp랑 stampscan밖에 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;stampscan은 src 만든 mikeinspace 꺼니까 인덱서 api를 알고 있고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;openstamp는 api 빌려다 쓴다고 듣기는 했는데..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확실하지는 않다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하여튼 이걸 오픈소스로 공개한다고 하니, 사람들은 호재로 인식하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 뭐 인덱서를 수정 중인건지 뭔지 assets에 갖고 있는 토큰이 안보여서 텔방에 사람들이 그 얘기만 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;rug당했다는 밈들도 보고 있음 재밌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;OKX의 댓글&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;okx 거래소 계정으로 src 관련 글에 LFG 달았다는게 핫하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;5774DE00-28E4-427A-8426-AC87D973FB88_1_201_a.jpeg&quot; data-origin-width=&quot;1121&quot; data-origin-height=&quot;1635&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWGxMU/btsB7ipiPJf/4qzP1olUziHkAoayYASAHk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWGxMU/btsB7ipiPJf/4qzP1olUziHkAoayYASAHk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWGxMU/btsB7ipiPJf/4qzP1olUziHkAoayYASAHk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWGxMU%2FbtsB7ipiPJf%2F4qzP1olUziHkAoayYASAHk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;409&quot; height=&quot;597&quot; data-filename=&quot;5774DE00-28E4-427A-8426-AC87D973FB88_1_201_a.jpeg&quot; data-origin-width=&quot;1121&quot; data-origin-height=&quot;1635&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;나의 근황&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요 며칠간 src-20 추가 구매하고 민팅도 몇 개 해봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kevin 좀 더 사고 Utxo, btc, doge, fake 도 민팅했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;민팅에 소모되는 가스비는 현재까지는 1회 25 ~ 40달러 정도 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;UTXO 민팅 끝&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;utxo가 계속 stampscan 트렌딩에 떠있길래 저거 뭐 있나 싶었는데 엄청난 속도로 민팅이 끝나고 엄청난 떡상을 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매수세가 장난 없다. 세력이 붙었나.. 상장까지 가는 건가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중국 쪽에서 사람들 많이 모이지 않았나 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이거 1회 민팅 30$면 했는데 지금 시세로 1,600$ 정도 된다 ㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;50배다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 가스비 싸지면 해야지 하고 자꾸 미뤘는데..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배아프긴 한데 뭐라도 성공하고 상장되면 좋다. 그게 src 생태계에 좋은 영향을 줄테니까&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-12-16 오후 2.26.17.png&quot; data-origin-width=&quot;2426&quot; data-origin-height=&quot;1386&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3aUHa/btsB4UpBnQ6/pLmooszMhdGOul45dcl4F0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3aUHa/btsB4UpBnQ6/pLmooszMhdGOul45dcl4F0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3aUHa/btsB4UpBnQ6/pLmooszMhdGOul45dcl4F0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3aUHa%2FbtsB4UpBnQ6%2FpLmooszMhdGOul45dcl4F0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;611&quot; height=&quot;349&quot; data-filename=&quot;스크린샷 2023-12-16 오후 2.26.17.png&quot; data-origin-width=&quot;2426&quot; data-origin-height=&quot;1386&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;src20에 대한 나의 생각&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재는 그냥 nft 같은 느낌이다. 어차피 그냥 밈코인인데 거래도 어렵고 수수료도 더럽게 비싸기 때문에 가격의 방향성이 정해지면 반대방향으로 돌리는게 매우 어렵다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;올라갈 때는 한없이 올라가고 떨어질 때는 끝도 없이 떨어지는..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 현재는 버블을 만들어 나가는 단계에 있지 않을까 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유는 우선 상장된 곳도 없고 커뮤니티가 그렇게 큰 건 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하루하루 커뮤니티가 커지고 있는게 느껴진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 거래소 상장으로 유동성을 확보하면 그 때부터가 시작이지 않나 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부정적인 의견으로는 확실히 brc-20을 넘기는 힘들 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;brc-20이야말로 거래소 상장을 통해 이제 많은 사람들이 메타라고 인지하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그만큼 많은 인지도, 시장 참여자 등의 증가세 기울기를 src가 넘기는 힘들지 않을까..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 나는 떨어지는 콩고물이 꽤 되지 않을까 라고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>blockchain (투자)</category>
      <author>uzzam</author>
      <guid isPermaLink="true">https://uzzam.tistory.com/49</guid>
      <comments>https://uzzam.tistory.com/49#entry49comment</comments>
      <pubDate>Sat, 16 Dec 2023 14:57:40 +0900</pubDate>
    </item>
    <item>
      <title>src-20 구매하기</title>
      <link>https://uzzam.tistory.com/48</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 ordinals에 관한 글을 올린 건&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://uzzam.dev/41&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://uzzam.dev/41&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1702483885013&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;비트코인 역사에 기록될 순간 Brc-20 1 - 개요&quot; data-og-description=&quot;개요 현재 암호화폐 투자는 안하고 있지만 습관이 되어 트위터로 소식은 자주 보고 있다. 최근의 이슈는 Pepe, 그리고 Brc-20이다. Pepe는 사실 바이낸스 상장까지 마친지 꽤 되었으니 이미 끝난 이&quot; data-og-host=&quot;uzzam.dev&quot; data-og-source-url=&quot;https://uzzam.dev/41&quot; data-og-url=&quot;https://uzzam.dev/41&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/pxTd7/hyULYy1Sz9/KbL5ka4q6eYP0fd6Yh5Ev1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/blDeY0/hyUL4F2NDQ/TsyxC1V9Ivst4EJ0qRuOIK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://uzzam.dev/41&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://uzzam.dev/41&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/pxTd7/hyULYy1Sz9/KbL5ka4q6eYP0fd6Yh5Ev1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/blDeY0/hyUL4F2NDQ/TsyxC1V9Ivst4EJ0qRuOIK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;비트코인 역사에 기록될 순간 Brc-20 1 - 개요&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;개요 현재 암호화폐 투자는 안하고 있지만 습관이 되어 트위터로 소식은 자주 보고 있다. 최근의 이슈는 Pepe, 그리고 Brc-20이다. Pepe는 사실 바이낸스 상장까지 마친지 꽤 되었으니 이미 끝난 이&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;uzzam.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2023년 5월 9일&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간이 이렇게나 흘렀다니 나도 놀랐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 사이에 비트코인을 비롯한 암호화폐 시장에도 생기가 돌고 있고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;누군가는 에어드랍으로 몇 천만원을 버는가 하면 brc-20 토큰인 ordi와 sats이 상장을 하기도 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 사실 에어드랍을 준비하거나, brc-20 토큰을 사놓지는 않았는데 그 이유는 돈이 없어서도 아니고 확신이 없어서도 아니고 단지 귀찮아서였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쨌든 후회되는 일이고 돌이켜보면 나에게 수익을 안겨다 준건 트레이딩이 아닌 온체인에서 다양한 활동을 할 때 인 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 지금 바로 미루지 않고 src-20 토큰을 사며, 다양한 활동을 해보려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어쩌면 내가 인간지표 일지도..?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;src-20 토큰이 뭔가?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 따로 글을 작성해서 링크를 달 예정&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;unisat wallet&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;src-20 토큰을 사기 위해 unisat 지갑을 선택했다. (다른 지갑도 가능하다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://unisat.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://unisat.io/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1702487613350&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;UniSat Wallet&quot; data-og-description=&quot;*Currently only Prime Access owners or addresses holding 400 UniSat Points are qualified.&quot; data-og-host=&quot;unisat.io&quot; data-og-source-url=&quot;https://unisat.io/&quot; data-og-url=&quot;https://unisat.io/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/CIZdM/hyUL4zeDpX/8Ms5e9SkduB9c2LktZBiR1/img.png?width=1200&amp;amp;height=256&amp;amp;face=0_0_1200_256,https://scrap.kakaocdn.net/dn/bAqIQx/hyUL0KnFrJ/xvCOtAP9z97bsFTRGu4tl0/img.jpg?width=708&amp;amp;height=1196&amp;amp;face=0_0_708_1196,https://scrap.kakaocdn.net/dn/iW9Tg/hyULVCjjSX/EsokLdEl7pHVlOWPNgRBy1/img.jpg?width=706&amp;amp;height=1200&amp;amp;face=0_0_706_1200&quot;&gt;&lt;a href=&quot;https://unisat.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://unisat.io/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/CIZdM/hyUL4zeDpX/8Ms5e9SkduB9c2LktZBiR1/img.png?width=1200&amp;amp;height=256&amp;amp;face=0_0_1200_256,https://scrap.kakaocdn.net/dn/bAqIQx/hyUL0KnFrJ/xvCOtAP9z97bsFTRGu4tl0/img.jpg?width=708&amp;amp;height=1196&amp;amp;face=0_0_708_1196,https://scrap.kakaocdn.net/dn/iW9Tg/hyULVCjjSX/EsokLdEl7pHVlOWPNgRBy1/img.jpg?width=706&amp;amp;height=1200&amp;amp;face=0_0_706_1200');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;UniSat Wallet&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;*Currently only Prime Access owners or addresses holding 400 UniSat Points are qualified.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;unisat.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;들어가서 크롬 익스텐션을 다운받아준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 후에는 지갑 생성하고 돈 전송하고 사면 끝이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-12-14 오전 1.17.06.png&quot; data-origin-width=&quot;710&quot; data-origin-height=&quot;1206&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1Fpq4/btsBTWOWFW5/N9NyrWzXOunkHH80KlH6yK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1Fpq4/btsBTWOWFW5/N9NyrWzXOunkHH80KlH6yK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1Fpq4/btsBTWOWFW5/N9NyrWzXOunkHH80KlH6yK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1Fpq4%2FbtsBTWOWFW5%2FN9NyrWzXOunkHH80KlH6yK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;215&quot; height=&quot;365&quot; data-filename=&quot;스크린샷 2023-12-14 오전 1.17.06.png&quot; data-origin-width=&quot;710&quot; data-origin-height=&quot;1206&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 지갑을 만들어준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 암호를 설정해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 그 후 12가지 phrase 를 안전하게 보관해주고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Address Type을 설정해주는데 Native Segwit(P2WPKH)로 해주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무거나해도 상관은 없다. 지갑 만든 후에 변경가능하기 때문에,,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;지갑완성 끝 !&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;비트코인 송금&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;업비트는 현재 전송 수수료가 0.0009BTC&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1비트에 6천만원이라 잡으면 한 번 송금할 때마다 54,000원씩 날아간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수수료를 조금 더 아끼고 싶다면 해외 거래소에 보내자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바이낸스의 전송 수수료는 0.000001 ~ 0.0004 BTC라고 되어있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;훨씬 싸다&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아 그리고 100만원 이상은 개인지갑 인증을 해야하는데 unisat 지갑은 업비트에 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 개인지갑을 쓴지가 이런 법적인? 것들이 생기기 전이라 잘 모르겠다. 목록에 없으니 아마 안되지 않을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쨌든 만만한 리플이나 트론을 사서 바이낸스로 전송 후 unisat으로 전송!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코인을 보내는 과정은 언제나 떨린다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;src-20 구매&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://openstamp.io/market&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://openstamp.io/market&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1702540945583&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;OpenStamp&quot; data-og-description=&quot;STAMPS IMPRINTING ETERNITY ON BITCOIN, ONE TRANSACTION AT A TIME.&quot; data-og-host=&quot;openstamp.io&quot; data-og-source-url=&quot;https://openstamp.io/market&quot; data-og-url=&quot;https://openstamp.io/market&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://openstamp.io/market&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://openstamp.io/market&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;OpenStamp&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;STAMPS IMPRINTING ETERNITY ON BITCOIN, ONE TRANSACTION AT A TIME.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;openstamp.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://www.stampscan.xyz&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;http://www.stampscan.xyz&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1702487116646&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;https://www.stampscan.xyz/trade&quot; data-og-description=&quot;&quot; data-og-host=&quot;www.stampscan.xyz&quot; data-og-source-url=&quot;http://www.stampscan.xyz&quot; data-og-url=&quot;https://www.stampscan.xyz/trade&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;http://www.stampscan.xyz&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://www.stampscan.xyz&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;https://www.stampscan.xyz/trade&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.stampscan.xyz&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 두 개의 사이트 중 싼 곳에서 사면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 openstamp의 존재를 몰랐어서 약간 비싸게 샀다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사이트가 직관적이기에 크게 어려움은 없다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-12-14 오전 2.10.18.png&quot; data-origin-width=&quot;2480&quot; data-origin-height=&quot;1616&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ag2Qu/btsB0fr6rYg/G3n4yduYW7PHATTbRSKrBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ag2Qu/btsB0fr6rYg/G3n4yduYW7PHATTbRSKrBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ag2Qu/btsB0fr6rYg/G3n4yduYW7PHATTbRSKrBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAg2Qu%2FbtsB0fr6rYg%2FG3n4yduYW7PHATTbRSKrBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;541&quot; height=&quot;353&quot; data-filename=&quot;스크린샷 2023-12-14 오전 2.10.18.png&quot; data-origin-width=&quot;2480&quot; data-origin-height=&quot;1616&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원하는 토큰의 Market에 들어가서&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-12-14 오전 2.19.59.png&quot; data-origin-width=&quot;2524&quot; data-origin-height=&quot;1622&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ItiJB/btsBY7OBFkz/DKgy3GZ0FZ3XNzatu80lHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ItiJB/btsBY7OBFkz/DKgy3GZ0FZ3XNzatu80lHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ItiJB/btsBY7OBFkz/DKgy3GZ0FZ3XNzatu80lHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FItiJB%2FbtsBY7OBFkz%2FDKgy3GZ0FZ3XNzatu80lHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;533&quot; height=&quot;343&quot; data-filename=&quot;스크린샷 2023-12-14 오전 2.19.59.png&quot; data-origin-width=&quot;2524&quot; data-origin-height=&quot;1622&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Buy를 누르면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-12-14 오전 2.20.16.png&quot; data-origin-width=&quot;1334&quot; data-origin-height=&quot;832&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSmwbm/btsBRRtzT6k/RWDZRyVJhDun80xDTXJQQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSmwbm/btsBRRtzT6k/RWDZRyVJhDun80xDTXJQQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSmwbm/btsBRRtzT6k/RWDZRyVJhDun80xDTXJQQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSmwbm%2FbtsBRRtzT6k%2FRWDZRyVJhDun80xDTXJQQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;599&quot; height=&quot;374&quot; data-filename=&quot;스크린샷 2023-12-14 오전 2.20.16.png&quot; data-origin-width=&quot;1334&quot; data-origin-height=&quot;832&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 식으로 뜬다. (수수료가 미쳤다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재는 장터처럼 사람들이 올린 걸 뭉텅이로 산다고 생각하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쨌든 위에 보이는 걸 산건 아니고 &lt;b&gt;STAMP, KEVIN, PEPE&lt;/b&gt;를 조금씩 샀다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;stamp는 openstamp에서 사고 kevin, pepe는 stampscan에서 샀다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹시 먼 미래에 src-20이 성공한다면 looksrare 처럼 토큰 에어드랍을 해줄지도 모르니까..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;구매 후&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구매 후에는 꽤나 많은 시간이 흘러야 가지고 있는 토큰을 확인 가능하다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 블록이 10분에 한 번꼴로 생기는 비트코인이다...&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안심하고 기다리면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;ETC.&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 왜 stamp, kevin, pepe를 샀을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 stamp, kevin은 src-20의 비트코인, 이더리움 정도라고 생각하고 pepe는 그냥 싸길래 사봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 재밌잖아~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;비트코인 네트워크 후기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수수료 보고 깜짝 놀랐다. 요즘 원래 이런건가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멤풀보고 깜짝 놀랐다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-12-14 오전 2.27.41.png&quot; data-origin-width=&quot;2442&quot; data-origin-height=&quot;1244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dN2tsN/btsBUA5mCav/DLtibmKuc5H3FwagVk6c00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dN2tsN/btsBUA5mCav/DLtibmKuc5H3FwagVk6c00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dN2tsN/btsBUA5mCav/DLtibmKuc5H3FwagVk6c00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdN2tsN%2FbtsBUA5mCav%2FDLtibmKuc5H3FwagVk6c00%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;579&quot; height=&quot;295&quot; data-filename=&quot;스크린샷 2023-12-14 오전 2.27.41.png&quot; data-origin-width=&quot;2442&quot; data-origin-height=&quot;1244&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨펌되지 않음 26만개? 원래 이런가,,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;옛날 이더리움에서 NFT 민팅이 핫했던 시절이 생각나는데..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; brc, src는 이더리움의 크립토 키티 정도 와 있는 걸까..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블록 사이즈를 늘리던가 하자......&lt;/p&gt;</description>
      <category>blockchain (투자)</category>
      <author>uzzam</author>
      <guid isPermaLink="true">https://uzzam.tistory.com/48</guid>
      <comments>https://uzzam.tistory.com/48#entry48comment</comments>
      <pubDate>Thu, 14 Dec 2023 02:35:00 +0900</pubDate>
    </item>
  </channel>
</rss>