메인 콘텐츠로 건너뛰기
StableNet은 Anzeon EVM을 실행합니다 — go-ethereum 포크로 London + Shanghai 옵코드와 Cancun 일부(blob 제외)를 구현합니다. 표준 EVM 개발 툴은 수정 없이 그대로 작동하며, StableNet에서만 반드시 지켜야 할 두 가지 사항이 있습니다.

사전 준비

이 페이지의 툴 스니펫을 사용하기 전에 아래 항목을 준비하세요:
  • Foundry (forge, cast) 또는 Hardhat 설치
  • 가스비 납부를 위한 WKRC 잔액이 있는 테스트넷 지갑

Faucet

무료 테스트넷 WKRC 받기 — 회원가입 불필요.

EVM 버전

항목
기반go-ethereum 포크 (Anzeon WBFT)
EVM 명령어 세트London + Shanghai + partial Cancun
PUSH0✅ 지원 (Shanghai)
Blob 트랜잭션 (type 0x03)❌ 미지원
최대 콜 스택 깊이1,024
Solidity 타겟paris 또는 shanghai 권장
Blob 옵코드(BLOBHASH, BLOBBASEFEE)는 사용할 수 없습니다. 컴파일러 설정에서 --evm-version cancun을 사용하지 마세요.

지원 툴

아래 모든 툴은 표준 테스트넷 RPC와 Chain ID로 작동합니다. 스니펫을 복사해 플레이스홀더 값만 교체하세요.
상태비고
Foundry (forge, cast)모든 브로드캐스트에 --priority-gas-price 필수
Hardhat배포 스크립트에 maxPriorityFeePerGas 설정 필요
MetaMaskwallet_addEthereumChain으로 커스텀 네트워크 추가
Remix IDE“External HTTP Provider”로 테스트넷 RPC 연결
ethers.js / viem각 트랜잭션에 maxPriorityFeePerGas 전달 필요

Foundry

foundry.toml에 StableNet 테스트넷 엔드포인트를 추가합니다:
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
# Blob 옵코드 미지원 — paris 또는 shanghai 사용
evm_version = "shanghai"

[rpc_endpoints]
stablenet_testnet = "https://api.test.stablenet.network"
모든 forge scriptcast send 브로드캐스트에 --priority-gas-price가 필요합니다:
forge script script/Deploy.s.sol \
  --rpc-url https://api.test.stablenet.network \
  --private-key $PRIVATE_KEY \
  --priority-gas-price 27600000000000 \
  --broadcast
cast send $CONTRACT "myFunction()" \
  --rpc-url https://api.test.stablenet.network \
  --private-key $PRIVATE_KEY \
  --priority-gas-price 27600000000000

Hardhat

// hardhat.config.js
require("@nomicfoundation/hardhat-toolbox");

module.exports = {
  solidity: {
    version: "0.8.20",
    settings: {
      evmVersion: "shanghai",  // cancun 사용 금지
    },
  },
  networks: {
    stablenet_testnet: {
      url: "https://api.test.stablenet.network",
      chainId: 8283,
      accounts: [process.env.PRIVATE_KEY],
    },
  },
};
배포 스크립트에서 Priority Fee를 지정합니다:
// scripts/deploy.js
const { ethers } = require("hardhat");

async function main() {
  const MyContract = await ethers.getContractFactory("MyContract");
  const contract = await MyContract.deploy({
    maxPriorityFeePerGas: ethers.parseUnits("27600", "gwei"),
  });
  await contract.waitForDeployment();
  console.log("Deployed to:", await contract.getAddress());
}

main().catch(console.error);

MetaMask

브라우저 콘솔에서 아래 코드를 실행해 StableNet 테스트넷을 MetaMask에 추가합니다:
await window.ethereum.request({
  method: "wallet_addEthereumChain",
  params: [
    {
      chainId: "0x205B",            // 8283 (hex)
      chainName: "StableNet Testnet",
      nativeCurrency: {
        name: "WKRC",
        symbol: "WKRC",
        decimals: 18,
      },
      rpcUrls: ["https://api.test.stablenet.network"],
      blockExplorerUrls: ["https://explorer.stablenet.network"],
    },
  ],
});

Remix IDE

  1. Remix IDE를 엽니다
  2. Deploy & Run 패널에서 EnvironmentExternal HTTP Provider로 설정합니다
  3. RPC URL 입력창에 https://api.test.stablenet.network를 입력합니다
  4. Remix가 Chain ID 8283을 자동으로 감지합니다
Remix UI는 maxPriorityFeePerGas 필드를 직접 노출하지 않습니다. MetaMask를 통한 트랜잭션은 Priority Fee 설정이 부족하면 실패할 수 있습니다. 안정적인 배포에는 Foundry 또는 Hardhat을 사용하세요.

ethers.js

테스트넷에 연결하고 모든 트랜잭션에 maxPriorityFeePerGas를 지정합니다:
import { ethers } from "ethers";

const provider = new ethers.JsonRpcProvider("https://api.test.stablenet.network");
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);

// StableNet은 27,600 Gwei 최솟값을 강제합니다 — 모든 트랜잭션에 포함
const tx = await wallet.sendTransaction({
  to: "0xRecipientAddress",
  value: ethers.parseEther("1.0"),
  maxPriorityFeePerGas: ethers.parseUnits("27600", "gwei"),
});
await tx.wait();
console.log("confirmed in block", tx.blockNumber);

viem

StableNet 테스트넷 체인 객체를 한 번 정의하고 클라이언트에서 재사용합니다:
import {
  createPublicClient,
  createWalletClient,
  http,
  parseEther,
  parseGwei,
} from "viem";
import { privateKeyToAccount } from "viem/accounts";

const stablenetTestnet = {
  id: 8283,
  name: "StableNet Testnet",
  nativeCurrency: { name: "WKRC", symbol: "WKRC", decimals: 18 },
  rpcUrls: {
    default: { http: ["https://api.test.stablenet.network"] },
  },
};

const publicClient = createPublicClient({
  chain: stablenetTestnet,
  transport: http(),
});

const account = privateKeyToAccount(process.env.PRIVATE_KEY);
const walletClient = createWalletClient({
  chain: stablenetTestnet,
  transport: http(),
  account,
});

// StableNet은 27,600 Gwei 최솟값을 강제합니다 — 모든 트랜잭션에 포함
const hash = await walletClient.sendTransaction({
  to: "0xRecipientAddress",
  value: parseEther("1.0"),
  maxPriorityFeePerGas: parseGwei("27600"),
});

StableNet 특유 동작

최소 Priority Fee: 27,600 Gwei

GovValidator 거버넌스 컨트랙트가 네트워크 전체에 최소 Priority Fee를 강제합니다. 이 값 미만의 maxPriorityFeePerGas를 가진 트랜잭션은 트랜잭션 풀에서 즉시 거절됩니다.
항목
최소 maxPriorityFeePerGas27,600 Gwei (27600000000000 wei)
적용 지점트랜잭션 풀 — 블록 포함 전 거절
컨트랙트 배포, 함수 호출, 네이티브 토큰 전송 등 모든 트랜잭션 타입에 적용됩니다. 현재 강제 값을 조회하려면:
curl -X POST https://api.test.stablenet.network \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_maxPriorityFeePerGas","params":[],"id":1}'
Ethereum과 달리, 이 메서드는 최근 블록 기반 예측값이 아닌 GovValidator 컨트랙트의 거버넌스 값을 반환합니다.

가스 정책

  • Base Fee: 동적 (네트워크 사용률에 따라 조정), 소각되지 않고 검증자에게 지급
  • Priority Fee: 거버넌스 최솟값, GovValidator가 강제
  • 블록 가스 한도: 105,000,000
  • 블록 생성 시간: ~1초

수수료 위임 (트랜잭션 타입 0x16)

StableNet은 별도 계정(FeePayer)이 발신자 대신 가스를 납부할 수 있는 수수료 위임 트랜잭션 타입을 지원합니다. 사용자 가스비를 앱이 대신 부담하는 UX에 활용할 수 있습니다.
항목
트랜잭션 타입0x16 (decimal 22)
활성화 조건Applepie 포크
필요 서명2개 — 발신자 + 수수료 납부자 (독립 서명)
EVM 내 tx.origin항상 발신자 (수수료 납부자 아님)
수수료 위임 트랜잭션 서명에는 StableNet RPC 확장 메서드를 사용합니다:
RPC 메서드설명
personal_signRawFeeDelegateTransaction패스워드 언락 계정으로 수수료 납부자 서명
eth_signRawFeeDelegateTransaction이미 언락된 계정으로 수수료 납부자 서명
서명이 완료된 트랜잭션은 eth_sendRawTransaction으로 제출합니다. ethers.js 서명 흐름 (provider.send) 타입 0x16은 StableNet 전용 트랜잭션 타입입니다. provider.send()로 RPC 메서드를 직접 호출합니다:
import { ethers } from "ethers";

const provider = new ethers.JsonRpcProvider("https://api.test.stablenet.network");

const SENDER      = "0xSenderAddress";
const FEE_PAYER   = "0xFeePayerAddress";
const RECIPIENT   = "0xRecipientAddress";

// Step 1: 발신자가 type 0x16 트랜잭션에 서명
// (노드에서 SENDER 계정이 언락되어 있어야 합니다)
const senderSignedRlp = await provider.send("eth_signTransaction", [{
  type:                 "0x16",
  from:                 SENDER,
  to:                   RECIPIENT,
  value:                ethers.toBeHex(ethers.parseEther("1.0")),
  gas:                  "0x5208",
  maxFeePerGas:         ethers.toBeHex(ethers.parseUnits("50000", "gwei")),
  maxPriorityFeePerGas: ethers.toBeHex(ethers.parseUnits("27600", "gwei")),
  nonce:                ethers.toBeHex(await provider.getTransactionCount(SENDER)),
  chainId:              "0x205B",   // 8283
  feePayer:             FEE_PAYER,
}]);

// Step 2: 수수료 납부자가 독립 서명 추가
// eth_signRawFeeDelegateTransaction (계정 이미 언락)
// 또는 personal_signRawFeeDelegateTransaction (패스워드 언락)
const fullySignedRlp = await provider.send("eth_signRawFeeDelegateTransaction", [
  senderSignedRlp,
  FEE_PAYER,
]);

// Step 3: 브로드캐스트 — 가스는 FEE_PAYER, 전송값은 SENDER에서 차감
const txHash = await provider.send("eth_sendRawTransaction", [fullySignedRlp]);
console.log("txHash:", txHash);
EVM 내부에서 tx.origin은 항상 발신자(SENDER)입니다. 수수료 납부자가 아닙니다. 스마트 컨트랙트는 수수료 위임 사용 여부를 감지할 수 없습니다.

네이티브 토큰의 ERC-20 이중성

네이티브 가스 코인(KRC)은 NativeCoinAdapter 시스템 컨트랙트를 통해 동시에 표준 ERC-20 토큰으로도 작동합니다. 별도 래핑이 필요 없으며, 가스에 사용되는 잔액과 balanceOf()로 조회되는 잔액이 동일합니다.
항목
컨트랙트 주소0x0000000000000000000000000000000000001000
심볼WKRC
소수점18
인터페이스ERC-20, FiatTokenV2_2 (USDC 호환)
표준 approve / transferFrom 패턴이 Ethereum과 동일하게 작동합니다.

미지원 / 제한 기능

기능상태비고
Blob 트랜잭션 (type 0x03)❌ 미지원Anzeon에 blob Cancun 옵코드 없음
BLOBHASH 옵코드 (0x49)❌ 미지원
BLOBBASEFEE 옵코드 (0x4a)❌ 미지원
eth_maxPriorityFeePerGas 오라클 동작⚠️ 동작 다름거버넌스 값 반환 (예측값 아님)
personal / admin / debug 네임스페이스⚠️ 공개 RPC 미노출로컬/개발 노드에서만 사용 가능
27,600 Gwei 미만 Gas Tip❌ 거절트랜잭션 풀 강제 적용

RPC 네임스페이스

공개 RPC 엔드포인트에서 사용 가능한 네임스페이스:
네임스페이스사용 가능
eth
net
web3
txpool
istanbul✅ (WBFT 합의 정보)
personal / admin / debug로컬 / 개발 노드 전용

다음 단계

첫 컨트랙트 배포

Foundry 단계별 튜토리얼 — WKRC 결제 컨트랙트를 약 15분 안에 배포합니다.

네트워크 정보

Chain ID, RPC 엔드포인트, 시스템 컨트랙트 주소.

API 레퍼런스

curl 및 ethers.js 예제가 포함된 전체 JSON-RPC 메서드 레퍼런스.

Explorer

온체인에서 트랜잭션, 컨트랙트, 계정을 조회합니다.

테스트넷 WKRC 받기

Faucet에서 무료 테스트넷 WKRC를 요청합니다.