solidity는 이더리움에서 smartContract를 정의할때 사용하는 언어로서 javascript에다가 몇가지 기능을 추가한 언어이다.


헬로월드 수준은: http://www.chaintalk.io/archive/lecture/86 

             간단한 dApp예제는 : http://www.chaintalk.io/archive/lecture/501


공부하기 가장좋은 사이트는 크립토좀비.



거기서 공부한 예제를 보면 다음과 같다.

pragma solidity ^0.4.19;

contract ZombieFactory {

// 여기에 이벤트 선언 - 이벤트는 나중에 별도로

uint dnaDigits = 16;
uint dnaModulus = 10 ** dnaDigits;

//struct: 생성자 자동, myZombie.name 으로 접근.

//struct내에서는 uint(256) 보다는 uint8을 쓰는게 가스소모량을 줄인다.

struct Zombie {
string name;
uint dna;
}

Zombie[] public zombies; //변수나 함수 되에 public/private 선언이 가능하다.

//private함수 및 param의 이름은 _로 시작하는게 관례

// internal: 자식class에서도 호출가능-private은 안됨 external: 외부에서만 호출가능

function _createZombie(string _name, uint _dna) private {
zombies.push(Zombie(_name, _dna));
// 여기서 이벤트 실행
}

//view:읽기만 하는 함수외부서호출시gas불소모, pure:다른변수 전혀 안쓰는 함수, return은 여러개도 가능

function _generateRandomDna(string _str) private view returns (uint) {
uint rand = uint(keccak256(_str)); //이더리움에서 지원하는 SHA함수로 16진수 return. uint로 변환필요
return rand % dnaModulus;
}

function createRandomZombie(string _name) public {
uint randDna = _generateRandomDna(_name);
_createZombie(_name, randDna);
}
}


<Event>

  

//선언
event NewZombieAdded(uint zombieId, string name, uint dna);

//이벤트 실행: dApp으로 신호보내기 임.
NewZombieAdded(id, _name, _dna); //id= zombies.push(..)-1 로 가능. push는 length리턴.


  이벤트 받는 예제는 : REF


<Mapping> 매핑은 말이 Mapping이지 사용법을 array와 동일하게 만들어 놨음.
      msg.sender 이용(해보자) : 컨트랙트내의 함수를 외부에서 호출한 사람주소


mapping (address => uint) favoriteZombieMap; function setMyNumber(uint _myNumber) public { // `msg.sender`에 대해 `_myNumber`가 저장되도록 `favoriteNumber` 매핑을 업데이트한다 ` favoriteZombieMap[msg.sender] = _myNumber; // ^ 데이터를 저장하는 구문은 배열로 데이터를 저장할 떄와 동일하다 }


<Require> Require는 if 함수와 비슷하지만,  조건이 안 맞으면 에러를 낸다.  

  solidity에는 string비교함수가 없으므로 SHA해시로 비교한다. 

require(keccak256(_name) == keccak256("Vitalik"));



<상속> 

contract ZombieFeeding is ZombieFactory {
}

  


<storage 및 메모리>
storage: HDD 또는 heap느낌.  블록체인에 영구저장됨.  contract의 멤버변수들도 여기 해당됨.
memory: RAM 또는 stack느낌.

대부분 storage/memory구분없이 사용해도 자동으로 되긴 하지만, function내에서 struct/array처리시 구분해서 사용해야할 경우가 있다.


<Interface>  

contract와 포맷이 동일한데, 내부함수에 body없음.

=> 다른 contract내의 함수를 호출할때 사용한다.

contract KittyInterface {
function getKitty(uint256 _id) external view returns (uint a);
}



<OpenZeppelin의 Ownable.sol>  => 이걸 상속받으면  onlyOwner modifier로 간단히  owner제약.  

owner 만 실행가능함. 

//1. import ownable.sol, 2. 상속 (is Ownable) 3.아래처럼 사용

function setKittyContractAddress(address _address) external onlyOwner {
kittyContract = KittyInterface(_address);
}


onlyOwner와 같은 modifier에 인자도 추가 가능.

modifier aboveLevel(uint _level, uint _zombieId) {
require(zombies[_zombieId].level > _level);
_; //실행코드가 한줄은 필요..
}



<각종 시간>

1 minutes :  60  임 (초단위까지 네요)

5 minutes: 300 

 secondsminuteshoursdaysweeksyears 같은 시간 단위 또한 포함하고 있다네. 이들은 그에 해당하는 길이 만큼의 초 단위 uint 숫자로 변환되네. 즉 1 minutes는 601 hours는 3600(60초 x 60 분), 1 days는 86400(24시간 x 60분 x 60초) 같이 변환

// 마지막으로 `updateTimestamp`가 호출된 뒤 5분이 지났으면 `true`를, 5분이 아직 지나지 않았으면 `false`를 반환 function fiveMinutesHavePassed() public view returns (bool) { return (now >= (lastUpdated + 5 minutes)); }



<Payable>

function levelUp(uint _zombieId) external payable {
require(msg.value == levelUpFee);
zombies[_zombieId].level++;
}


//인출 코드 예제.
uint itemFee = 0.001 ether; msg.sender.transfer(msg.value - itemFee);



Posted by yongary
,


build.gradle에서 npm run build 수행방법:


plugins {
id "com.moowork.node" version "1.2.0"
}
apply plugin: 'com.moowork.node'
task npmBuild(type: NpmTask) {
args = ['run-script','build']
}
build.dependsOn npmBuild



그리고, jar하면서 react.js의 결과파일을 static으로 넣는 방법은

 web-frontend 프로젝트를 별도로 만들고, (위의 build.gradle작업은 여기서 하고)


메인 spring-boot-webapp 프로젝트의 build.gradle에서   아래와 같이  의도적으로 build밑에껄 복사해준다.

jar {
//blabla
from {
configurations.compile.collect {it.isDirectory()? it: zipTree(it)}
}
into('static') {
from('../web-frontend/build')
}
}


Posted by yongary
,

Ajax axios, Redux

React.js 2018. 2. 25. 23:26


React에서 ajax기능을 사용할때는 axios HttpClient를 많이 사용한다.   REF



  axios.get('/user?id=velopert')

    .then( response => { console.log(response); } ) // SUCCESS
    .catch( response => { console.log(response); } ); // ERROR

axios.post('/msg', { user: 'velopert', message: 'hi' }) .then( response => { console.log(response) } ) .catch( response => { console.log(response) } ); //catch는 생략가능

//IE 호환문제 ? babe-polyfill로 해결? -> test해보자.

class 활용 예제. 

https://laracasts.com/discuss/channels/servers/get-data-out-from-axios-javascript



Redux 는 study중:    dispatcher방식으로 state관리  https://velopert.com/1225   




=================물론 jquery $.ajax도 사용할 수 있다 =================


 (POST앞에 있는것은 커서임)


출처:유투브



Posted by yongary
,

키보관 방법

블록체인 2018. 2. 18. 00:03

키나 IOTA seed를 암호화해서 보관하고 싶으면


파일을 알집으로 암호넣어서 zip을 한다음에


axcrypt.net에서 프로그램을 다운받아서 아주 긴 비번으로 로그인을 해서, 암호화를 하도록 한다.

256bit 알고리듬으라 안전하다.  



Posted by yongary
,

kubernetes

SDN,cloud,Puppet 2018. 2. 12. 19:19

Docker를 여러개의 host에서 쓴다던지 하는 경우로 인해,

서로 다른 Host내의 docker끼리 통신을 해야한다면(inter-host comm.)


Kubernetes를 사용하면 된다. 

Kubernetes에는 그 외에도 몇가지 기능이 있는데.. 


Posted by yongary
,

비트코인 지갑

블록체인 2018. 2. 1. 23:07

 REF

 비트코인 지갑 : 처음들으면 Bitcoin이 들어있는 것으로 착각들을 하지만, 실제로는 private키만 보관한다.

   종류는 인터넷에 연결된 Hot Wallet과  그렇지 않은 Cold Wallet이 있고 ,   HD(계층 결정적)Wallet도 참고삼아 보자.


  Hot Wallet - full node에는 full wallet,  SPV Node에는 SPV(Simple Payment Verification) wallet. 

                     전체 blockchain을 저장하지 않으면서 full node들의 메모리를 이용하는 가벼운 장점으로 인해, 모바일을 비롯해 많은 SPV wallet들이 발전중이다.


  Cold Wallet - 종이나 USB 혹은 특별히 제작된 Hardware와 같이 offline으로 private key를 저장하는 Wallet.




  HD Wallet - 24개 이하의 단어를 쓰면 private key를 생성해줘서 약간 외울수 있는 수준의 private key를 만들어 주는 지갑.

             brain Wallet도 비슷한 개념인거 같네요.   암튼 이것도 단어는 추측이 쉬워서 보안에 취약하다는 거...  

        정리하면) 단어를 이용해 pk를 만들거나 단어를 통해 pk를 암기하는 방식으로 pk를 안외워도 되는 방식이지만 보안에 썩 좋진 않음

        ==> 그래도  왠지 이게 끌리네요. 가성비가 좋을듯. 



 -------------  private key를 보관하지 않는 wallet --------  비트코인 지갑이라고 부를수 없을것 같구요

  Web Wallet- pk를 3자에게 맡긴 것으로, 거래소 등에 Wallet을 맡겼다고 보면 된다.  당근 위험!  

Posted by yongary
,

jQuery의 팝업 기능으로 간단히 이쁜 layer팝업을 만들수 있다.

 - 이걸 모를때는 bootstrap을 사용했었는데, jQuery가 더 편하다.

  (이쁘기는 bootstrap이 더 이쁠 것 같아요)



- 사용법도 간단하다.  REF


1. jquery관련 인클루드

  <script type="text/javascript" src="blabla/js/jquery.popup.min.js"></script>


2. html 팝업코딩

  <div id="popup" class="pop_style">

     blabla

  

3. jquery로 호출.

  뛰우기:  $('#popup').bPopup();


  close:   $('#popup').bPopup().close();

Posted by yongary
,

Excel upload

springBoot gradle 2018. 1. 23. 11:46

 poi 이용 : 한글 REF 

    영문: REF



1. maven dependency 추가.

<dependency>

<groupId>org.apache.poi</groupId>

<artifactId>poi</artifactId>

<version>3.15</version>

</dependency>

         <dependency>

            <groupId>org.apache.poi</groupId>

            <artifactId>poi-ooxml</artifactId>

            <version>3.15</version>

        </dependency>

<dependency>

            <groupId>org.apache.poi</groupId>

            <artifactId>poi-ooxml-schemas</artifactId>

            <version>3.15</version>

        </dependency>

        <dependency>

            <groupId>org.apache.poi</groupId>

            <artifactId>poi-contrib</artifactId>

            <version>3.6</version>

        </dependency>


2. JSP

function fnCheckUpload() {

var file = $("#excel").val();

if(file == "" || file == null){

alert("먼저 파일을 선택하세요.");

return false;

}

var fileFormat = file.split(".");

var fileType = fileFormat[1];

if(confirm("업로드 하시겠습니까?")){

$('#excelUpForm').attr('action','/uploadMoveinExcel.do');

var options = {

fail:function(data) {

        alert('저장 오류가 발행하였습니다.');

        $('#popup').bPopup().close();

        },

success:function(data){

alert(data + "건 업로드 완료");

$('#popup').bPopup().close();

},

type: "POST",

data : {"excelType" : fileType}

};

$('#excelUpForm').ajaxSubmit(options);

}

}

-----HTML--------

<form id="excelUpForm" method="post" action="" role="form" enctype="multipart/form-data">

                                    <input  id="excel" name="excel" class="file" type="file"  >


</form>



3. controller

  @ResponseBody

@RequestMapping(value="/uploadMoveinExcel.do")

public String uploadExcel( MultipartHttpServletRequest request, HttpSession session) {

List<ExcelVo> list = new ArrayList<>();

String excelType = request.getParameter("excelType");

log.info("uploadExcel.do + excelType:" + excelType);

if(excelType.equals("xls")){

list = moveinService.xlsExcelReader(request);

}else if(excelType.equals("xlsx")){

//IN_STUDY:  list = adminAccountsMngService.xlsxExcelReader(req);

}

int cnt = service.uploadList(list);

return String.valueOf(cnt);//success cnt : media처리의 경우, JSON포맷으로 잘 안변함(config필요), 따라서 간단히 숫자만 리턴.

}


4. service

  public List<MoveinExcelVo> xlsExcelReader(MultipartHttpServletRequest request) {

// 반환할 객체를 생성

List<MoveinExcelVo> list = new ArrayList<>();


MultipartFile file = request.getFile("excel");

HSSFWorkbook workbook = null;


try {

// HSSFWorkbook은 엑셀파일 전체 내용을 담고 있는 객체

workbook = new HSSFWorkbook(file.getInputStream());


// 0번째 sheet 반환

HSSFSheet curSheet = workbook.getSheetAt(0);  //workbook.getNumberOfSheets()

// row 탐색 for문

boolean isInTable = false;

for (int rowIndex = 0; rowIndex < curSheet.getPhysicalNumberOfRows(); rowIndex++) {

//헤더 Cell 찾기.

String firstCellValue = curSheet.getRow(rowIndex).getCell(0).getStringCellValue();

if ("구분".equals(firstCellValue.trim())) { //table헤더 발견.

isInTable = true;

continue; //헤더는 pass.  (다움줊부터 paring시작.)

}

if (isInTable) { //in Table 파싱 시작. ///////////////////////////////////////////

HSSFRow curRow = curSheet.getRow(rowIndex);

//필수 Cell들.

String cellStr = curRow.getCell(2).getStringCellValue(); //String 읽기

String cellDate =  StringUtil.toYYMMDD(curRow.getCell(5).getDateCellValue()); //날짜 읽기

String cellNum = curRow.getCell(7).getNumericCellValue() + ""; //산차.

  String cellLongNUm = StringUtil.toIntString(curRow.getCell(12).getNumericCellValue() ;   //엄청 긴 숫자 읽기

. . . . 

} catch (IOException e) {

e.printStackTrace();

}


// vo로 만들면서 db에 삽입코드는 생략.

return list;

}


public class StringUtil {


    private static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

    public static String datePattern = "^\\d{4}[\\-](0[1-9]|1[012])[\\-](0[1-9]|[12][0-9]|3[01])$";

    public static boolean isDate(String str) {

    return Pattern.matches(datePattern, str);

    }

    //return YYYY-MM-DD String

    public static String toYYMMDD(Date date) {

    return formatter.format(date);

    }

    public static boolean isNumericOrFloat(String str) {

        if (str == null) {

            return false;

        }

        int sz = str.length();

        for (int i = 0; i < sz; i++) {

            if (Character.isDigit(str.charAt(i)) == false) {

            if (str.charAt(i) != '.')  //Added KY. '.'도 numeric으로 간주. float때문에.

            return false;

            }

        }

        return true;

    }

    

    //For Excel processing.

    // 엑셀에선 숫자를 항상 double로 읽기 때문에 int형태의 String으로 변환하면 유용.

    public static String toIntString(double doubleVal) {

    try {

    BigInteger k = new BigDecimal(doubleVal).toBigInteger();

    

    return String.valueOf(k);

   

    } catch (Exception e) {

    return null;

    }

    }

Posted by yongary
,

특수기능

ElasticSearch 2018. 1. 22. 21:38

template: 여러개의 template을 지정해 놓을 수 있음.

     -> 잘못 사용하면 여기에 계속 걸려서, insert가 안되는 경우도 있으니 조심필요.



join: 부모-child관계 지정.   (예:질문-답변)  REF

       RDB의 relation과 어느정도는 유사하게 사용이 가능하지만,

       one-to-many 관계에서만 사용하는 게 좋다. 

       (그리고, 한 index안에서만 사용한다 )


 -Relation: 부모와 자식관계 설정

 -Child 여러 개 설정 가능

- (손자)Child 밑에 Child를 둘 수 있음





_segment: segment내의 data까지 조회가 가능하다.





Posted by yongary
,

js 모듈화 코딩기법

jquery 2018. 1. 2. 09:14

http://www.nextree.co.kr/p4150/  

Posted by yongary
,