TIL 42 - Golang으로 블록체인 만들기(Wallet) - 12 - 2

프동프동·2023년 2월 10일
0

TIL

목록 보기
42/46
post-thumbnail

wallet 만들기

변수 & 상수

type wallet struct {
	// 아무와도 공유되지 않는다.
	privateKey *ecdsa.PrivateKey
	// 16진수 문자열의 public key가 된다.
	Address string
}

// Singleton을 위해 초기화되지 않은 wallet 선언
var w *wallet

const (
	fileName string = "fdongfdong.wallet"
)

함수

Wallet() : 함수 호출 시 사용자가 wallet이 없다면 키페어를 만들어 파일 형태로 저장해준다.

// Singleton 패턴 사용
func Wallet() *wallet {
	if w == nil {
		w = &wallet{}
		// 사용자가 이미 지갑을 가지고 있는지 확인한다.
		if hasWalletFile() {
			w.privateKey = restoreKey()
			// 만약 있다면 그 키를 파일로부터 복구한다.
		} else {
			// 만약 없다면..
			// 키페어를 만들어서
			key := createPrivKey()
			// 파일에 저장해둔다.
			persistKey(key)
			// 생성한 키페어를 등록한다.
			w.privateKey = key
		}
		w.Address = aFromK(w.privateKey)
	}
	return w
}

hasWalletFile() : 해당하는 파일의 이름을 가진 파일이 존재하는지 알려준다.

func hasWalletFile() bool {
	_, err := os.Stat(fileName)
	return !os.IsNotExist(err)
}

resotoreKey() : 키 파일을 읽어 해당 키를 반한한다.

// named return을 사용하면 variable을 미리 초기화시켜준다.
// return 시 알아서 리턴시켜준다.
// 매우 짧은 function에서 사용해야한다.
func restoreKey() (key *ecdsa.PrivateKey) {
	keyAsByte, err := os.ReadFile(fileName)
	utils.HandleErr(err)
	// x509 : private key를 parse, mershall 할 수 있다.
	key, err = x509.ParseECPrivateKey(keyAsByte)
	utils.HandleErr(err)
	return
}

createPrivKey() : Key Pair를 생성해준다.

  • Public Key
  • Private Key
func createPrivKey() *ecdsa.PrivateKey {
	// 키페어를 생성해준다.
	privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	utils.HandleErr(err)
	return privKey
}

persistKey() : key를 받아 byte 타입의 파일로 저장한다.

func persistKey(key *ecdsa.PrivateKey) {
	// private key를 받아서 byte slice로 만든다.
	bytes, err := x509.MarshalECPrivateKey(key)
	utils.HandleErr(err)
	// 0644 : 읽기와 쓰기 허용
	err = os.WriteFile(fileName, bytes, 0644)
	utils.HandleErr(err)
}

aFormK() : private key에서 public key를 가져온다.

func aFromK(key *ecdsa.PrivateKey) string {
	return encodeBigInts(key.X.Bytes(), key.Y.Bytes())
}

encodeBigInts() : public key의, a,b 값을 합쳐 16진수 문자열형태로 반환한다.

func encodeBigInts(a, b []byte) string {
	// public key의 a, b값을 합쳐서 16진수 문자열형태로 반환한다.
	z := append(a, b...)
	return fmt.Sprintf("%x", z)
}
profile
좋은 개발자가 되고싶은

0개의 댓글