function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);

        _afterTokenTransfer(address(0), to, tokenId);
    }

둘의 차이는 safeMint의 경우 mint 하려고 하는 address가 실제로 존재하는지 체크 하는 로직이 구현되어있다.

_safeMint가 실행 되면 토큰이 전송된 후에 _checkOnERC721Received 함수가 호출되고 정상적으로 이루어지지 않을경우에는 트랜잭션을 되돌리게 됩니다.

   function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }
    
    
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

 

 

'코딩이야기 > blockchain' 카테고리의 다른 글

Web3j  (0) 2023.10.24
SmartContract 프레임워크 선택  (0) 2022.12.13
ERC20 토큰 발행 및 ERC721 NFT 발행  (0) 2022.11.21

Remix 

온라인 Solidity 용 IDE 이며 디버깅 및 테스트를 제공하며, 간단한 Smart contract 를 작성하는데 최적이다.

빠르고 간단한 테스트에 최적이지만 복잡한 로직에는 부적절하다.

Truffle - 스마트 컨트랙트 개발 프레임워크

솔리디티 코드 개발을 로컬에서 보다 편리하게 개발 할 수 있도록 지원해주는 프레임워크이다.

Truffle 은 web3.js 라이브러리를 채택하고 있다.

 

truffle 단점으로 Verify 가 자동으로 지원되지 않는다라고 한다.

최근에는 Hardhat 이라는 프레임워크를 많이 사용하는것 같다. 

HardHat

위에 개발 도구들에 비해 보다 전문개발 도구이며, 작성, 컴파일, 테스트, 배포 등을 가능함

turffle 에 비해 내부적으로 가상 이더리움 네트워크를 제공해주어 별도의 ganache가 필요하지 않는다.

Verify 를 자동으로 지원한다.

Typechain  플러그인을 지원하여 .sol 파일을 타입스크립트로 된 artifact 를 만들어준다.

Hardhat 은 Ethers.js 라이브러리를 사용한다.

 

 

개발환경 셋팅하기

Intellij 에 Soildity 플러그인 설치

자신이 원하는 위치에 비어있는 프로젝트 폴더 생성 후 soildity 파일을 생성합니다.

Hardhat설치

  • node는 기존에 설치가 되어있다는 전제로 진행한다.
  • 설치 버전 2.12.2

https://hardhat.org/guides/project-setup.html

 

Hardhat | Ethereum development environment for professionals by Nomic Foundation

Hardhat is an Ethereum development environment. Compile your contracts and run them on a development network. Get Solidity stack traces, console.log and more.

hardhat.org

npm(Node Package Manager) 이란?

  • node.js의 모듈 관리를 하기 위한 도구
npm install --save-dev hardhat
npx hardhat

 

npx hardhat

 

 

아래와 같이 hardhat 설치 및 solidity를 이용한 SmartContract 작성준비가 끝났습니다. 

열심히 코딩을 시작합니다.

 

'코딩이야기 > blockchain' 카테고리의 다른 글

Web3j  (0) 2023.10.24
_mint vs _safeMint 차이점  (1) 2022.12.23
ERC20 토큰 발행 및 ERC721 NFT 발행  (0) 2022.11.21

openzeppelin을 이용하여 ERC20 기반의 토큰을 Sepolia 테스트넷에 발행 및 ERC721 기반의 NFT 발행하는 작업을 진행해보겠다.

 

yarn add @openzeppelin/contracts

openzeppelin 을 설치하고 싶었지만.... node의 버전 문제가 생겼고 다운그레이드를 진행하였다.

 

내 node --version 은 19.0.1 이고 hardhat이 지원하는 18.0.0.으로 변경하고자 node 버전 관리 모듈인 n을 이용하려고 한다.

 

 

npm install n
sudo n 18.0.0 

n 설치후 노드 버전을 변경하고 싶었으나 

installed된 노드 위치와 active된 노드의 위치가 달라서 노드 버전을 계속 새로 설치하고 버전을 변경해도 active된 노드 버전이 변경되지 않는다고 한다...

 

드럽게 안된다...

실패...

node, nvm, npm 다 지우고 다시 한다...


ERC721 NFT를 발행해보자...

 

ERC721 용 폴더를 생성합니다.

 

npx hardhat

npx 를 이용해서 hardhat 을 설치합니다.

hardhat을 설치하게 되면 위에 사진처럼 샘플 프로젝트가 생성됩니다.

NFT를 생성하기 위해 openzeppelin을 설치 합니다.

npm install @openzeppelin/contracts

 

 

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract Artwork is ERC721 {
    uint256 public tokenCounter;
    mapping (uint256 => string) private _tokenURIs;

    constructor(
        string memory name,
        string memory symbol
    ) ERC721(name, symbol) {
        tokenCounter = 0; //초기 민트하는 nft의 횟수를 0으로 지정합니다.
    }

    function mint(string memory _tokenURI) public {
        _safeMint(msg.sender, tokenCounter);
        _setTokenURI(tokenCounter, _tokenURI);

        tokenCounter++;
    }

    function _setTokenURI(uint256 _tokenId, string memory _tokenURI) internal virtual{
        require(
            _exists(_tokenId),
            "ERC721Metadata : URI set of nonexistent token"
        );
        _tokenURIs[_tokenId] = _tokenURI;
    }

    function tokenURI(uint256 _tokenId) public view virtual override returns(string memory){
        require(
            _exists(_tokenId),
            "ERC721Metadata: URI set of nonexistent token"
        );
        return _tokenURIs[_tokenId];
    }
}

//코드 설명

 

 

 

 

npx hardhat compile

npm install --sava-dev chai

스마트컨트랙트의 경우 자바와 다르게 한번 배포하면 수정은 불가하기에 테스트 코드가 굉장히 중요하다.

 

/test 디렉토리 안에 테스트 파일을 작성합니다. 

const { expect } = require('chai');
const { ethers } = require("hardhat")

describe("Artwork Smart Contract Tests", function() {

    this.beforeEach(async function() {
        // This is executed before each test
        const Artwork = await ethers.getContractFactory("Artwork");
        artwork = await Artwork.deploy("Artwork Con", "ART");
    })

    it("NFT is minted successfully", async function() {
        [account1] = await ethers.getSigners();

        expect(await artwork.balanceOf(account1.address)).to.equal(0);

        const tokenURI = "https://opensea-creatures-api.herokuapp.com/api/creature/1"
        const tx = await artwork.connect(account1).mint(tokenURI);

        expect(await artwork.balanceOf(account1.address)).to.equal(1);
    })

    it("tokenURI is set sucessfully", async function() {
        [account1, account2] = await  ethers.getSigners();
        const tokenURI_1 = "https://opensea-creatures-api.herokuapp.com/api/creature/1"
        const tokenURI_2 = "https://opensea-creatures-api.herokuapp.com/api/creature/2"

        const tx1 = await artwork.connect(account1).mint(tokenURI_1);
        const tx2 = await artwork.connect(account2).mint(tokenURI_2);

        expect(await artwork.tokenURI(0)).to.equal(tokenURI_1);
        expect(await artwork.tokenURI(1)).to.equal(tokenURI_2);

    })

})

테스트 결과

 

npx hardhat test

 

.env 파일을 이용해서 환경변수 방식을 사용하기 위해 dotenv를 설치합니다.

 

npm install dotenv

npm install @nomiclabs/hardhat-etherscan

 

hardhat.config.js 파일을 수정합니다.

require("@nomiclabs/hardhat-waffle");
require("@nomiclabs/hardhat-etherscan")
require("dotenv").config();

task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
  const accounts = await hre.ethers.getSigners();

  for (const account of accounts) {
    console.log(account.address);
  }
});

task("deploy", "Deploy the smart contracts", async(taskArgs, hre) => {

  const Artwork = await hre.ethers.getContractFactory("Artwork");
  const artwork = await Artwork.deploy("Artwork Contract", "ART");

  await artwork.deployed();

  await hre.run("verify:verify", {
    address: artwork.address,
    constructorArguments: [
      "Artwork Contract",
      "ART"
    ]
  })

})

module.exports = {
  solidity: "0.8.4",
  networks: {
    mumbai: {
      url: "https://matic-testnet-archive-rpc.bwarelabs.com",
      accounts: [
        process.env.PRIVATE_KEY,
      ]
    }
  },
  etherscan: {
    apiKey: process.env.POLYGONSCAN_KEY,
  }
};

 

 

 

npx hardhat deploy --network mumbai

deploy를 진행하는데 오류가 나네요... hardhat-waffle 모듈을 찾을수 없는 문제입니다.

npm install @nomiclabs/hardhat-waffle

실패....

Reason: The Etherscan API responded that the address 0x43aAB3Bf55ee50dCE2b3894393C3948394A47cba does not have bytecode.

이런 오류가 발생하면서 작동하지 않는다... 온갖 방법을 다 써도 안된다...


임시해결

위에 오류가 난 이유로는 etherscan api 자체의 오류로 다들 비슷한 오류를 겪고 있다. 하지만 나는 해당오류랑 또다른 오류에 봉착한 상태이다….

이를 임시로 컨트랙트의 주소를 로그로 찍은뒤 검증하는 부분에 로그로 찍은 주소를 입력했다.

생성한 컨트랙트의 주소를 확인할수 있고 TestNet Scan에서 확인할 수 있다.

https://mumbai.polygonscan.com/

 

TESTNET Polygon (MATIC) Blockchain Explorer

PolygonScan allows you to explore and search the Polygon blockchain for transactions, addresses, tokens, prices and other activities taking place on Polygon (MATIC)

mumbai.polygonscan.com

ipfs metadata 값을 이용해야합니다.

저는 pinta라는 ipfs지원 하는 친구를 사용하였습니다.

https://app.pinata.cloud/pinmanager

 

Pinata

Effortless IPFS File Management

app.pinata.cloud

metamask 연결한 뒤 mint 영역 URI 부분에 ipfs 형태의 이미지 주소를 입력후 Write 를 누르게 되면 아래 사진과 같이 발행이 가능합니다.

https://testnets.opensea.io

 

 

 

 

'코딩이야기 > blockchain' 카테고리의 다른 글

Web3j  (0) 2023.10.24
_mint vs _safeMint 차이점  (1) 2022.12.23
SmartContract 프레임워크 선택  (0) 2022.12.13

 

배당요구종기일이 2021-12-01 이다.임차인은 2021-12-02일 하루 늦게 배당요구를 신청했다

배당종기일 이후에 배당요구를 했기 때문에 대항력이 있기 때문에 보증금을 낙찰자가 인수하게 된다.

위와 비슷한 사건으로 매우 싸다고 느껴지는 물건이다.

호갱노노 실거래가는 동일평수 11억 가량된다. 매매물건은 10억 5천 급매 기준 9억 5천 ~ 10억 예상된다.

추가로 임차인이 있고 보증금은 6억이다.

4차 최저매각 금액 4억 8천 + 6억 = 10억 8천이 되겠다.... 한번더 유찰되어야 구미가 당길 가격이다.

 

 

위에서 배당요구종기일 보다 늦게 배당신청한 사건이고 밑으로는 배당요구종기일에 맞추어 배당신청한 사건에 대해 조사해봐야겠다.

 

 

 

 

 

 

 

 

 

 

 

세상은 아는만큼 보이고 보는만큼 보인다.

겉만 보고 판단하지 말자

POJO란 무엇인가?

Plain Old Java Object, 간단히 POJO는 말 그대로 해석을 하면 오래된 방식의 간단한 자바 오브젝트라는 말로서 Java EE 등의 중량 프레임워크들을 사용하게 되면서 해당 프레임워크에 종속된 "무거운" 객체를 만들게 된 것에 반발해서 사용되게 된 용어이다(위키피디아)

POJO의 필수 요소로는 가볍고, 유연하고, 간단명료 함이 있다.

장점 :

  • 특정 프레임워크에 종속되지 않은 프로그래밍.
  • 모든 java 프로그램에서 사용이 가능하다.
  • 특정 프레임워크에 종속되지 않기 때문에 테스트가 자유롭다.

규칙

  • 멤버변수의 접근자는 private
  • 멤버 변수마다 getter/setter 가 존재
  • getter/setter 메소드의 접근자는 public

POJO 클래스는 가독성과 재사용 성을 높이기 위해 객체를 정의하는 데 사용되므로 Bean과 유사합니다. Bean에는 몇 가지 제한이 있지만 POJO 파일에는 특별한 제한이 없다는 유일한 차이점이 있습니다.

 

JAVA POJO 예시코드

public class pojo {  
private String name;  
private String id;  
private double sal;  
public String getName() {  
    return name;  
}  
public void setName(String name) {  
    this.name = name;  
}  
public String getId() {  
    return id;  
}  
public void setId(String id) {  
    this.id = id;  
}  
public double getSal() {  
    return sal;  
}  
public void setSal(double sal) {  
    this.sal = sal;  
}  
}

 

POJO vs Bean

Pojo에는 Java 규칙 외에 특별한 제한이 없습니다. Java 규칙 이외의 몇 가지 특별한 제한 사항이있는 특수 유형의 POJO 파일입니다.
Bean에 비해 필드에 대한 제어가 적습니다. 필드에 대한 완전한 보호를 제공합니다.
POJO 파일은 Serializable 인터페이스를 구현할 수 있습니다. 그러나 필수는 아닙니다. Bean 클래스는 Serializable 인터페이스를 구현해야합니다.
POJO 클래스는 이름을 사용하여 액세스 할 수 있습니다. Bean 클래스는 getter 및 setter를 사용해야 만 액세스 할 수 있습니다.
필드에는 public, private, protected와 같은 액세스 수정자가있을 수 있습니다. 필드는 개인 액세스 권한 만 가질 수 있습니다.
POJO에서는 인수가없는 생성자가 필요하지 않습니다. 가질 수도 있고 없을 수도 있습니다. 인수가없는 생성자가 있어야합니다.
POJO 사용에 대한 불이익은 없습니다. Bean 사용의 단점은 Default 생성자와 public setter가 불변이어야 할 때 객체 상태를 변경할 수 있다는 것입니다.

'코딩이야기 > JAVA' 카테고리의 다른 글

Callable 비동기 삽질 방지  (0) 2021.01.26
[JAVA]  (0) 2020.06.29
[JSP&Servlet]  (0) 2020.05.28
[JAVA]입출력  (0) 2020.05.01
[JAVA] 람다식  (0) 2020.04.29

+ Recent posts