체인의정석

블록체인 공증 모듈 - 게시판 기능 만들기, 양쪽의 동의를 얻은 후 블록체인에 데이터 저장시키기 본문

개발

블록체인 공증 모듈 - 게시판 기능 만들기, 양쪽의 동의를 얻은 후 블록체인에 데이터 저장시키기

체인의정석 2021. 1. 7. 04:17
728x90
반응형

1. 파일 첨부기능

 

다음과 같이 파일을 올릴시 파일의 해시값을 바로 보여주는 기능을 연결하였다. 일단 이 기능을 하고 난 후 블록체인에 저장버튼을 양쪽 사용자가 같이 누르게 되면 DB값을 변화시켜 블록체인에 저장시키게 만드는 식으로 개발할 예정이다.

 

        $("#contract").change(function(e){
            e.preventDefault()
            if($("#contract").val()){
                let form = $("#add_board")[0];
                console.log("form",form);
                let formData = new FormData(form);
                console.log("formData",formData);
                // formData.append("bidx",$("#bidx").val())
    
                $.ajax({
                    type: "POST",
                    processData: false,
                    contentType: false,
                    enctype: 'multipart/form-data',
                    url : 'blockchain/file_idx_view',
                    data : formData,
                    success: function(r){
                        let filehash = r.data.file_hash;
                        $("#file_hash").val(filehash);
                    },
                    error: function(){
                        location.href="/error";
                    }
                })
            }  
        });  
        $(".contract_display").hide();

change를 event로 두고 파일이 올라가면 해시를 만들어서 리턴하는 API를 호출한다. 이후 파일해시에 이를 넣어주면 된다.

router.post('/file_idx_view', upload.single("contract"), async function(req,res){
    console.log("file_idx_view")
    let rf = req.file;
    console.log(rf);
    let file_path = rf.path;

    //해시하기
    let file_hash = await get_hash(file_path);
    console.log("file_hash >>>" ,file_hash);

    if(file_hash){
        res.send(JSONResponse.successTrue({"file_hash":file_hash}))
    }else{
        console.log("get hash fail")
    }
});

이전에 만들어둔 get_hash함수를 사용하여 진행하였다.

 

const get_hash = async(targetFile) => {
    return new Promise(async(resolve, reject) => {
        const hash = crypto.createHash('sha256'); // 초기화를 위해 여기서 실행
        let input = fs.readFileSync(targetFile);
        console.log("get hash input >>> " ,input)
            if(input){
                hash.update(input);
                let output = hash.digest('hex');
                console.log(output)
                resolve(output);
            }else{
                reject("hash error");
            }
    })
}

get hash 함수는 다음과 같이 파일을 읽어와서 해시로 변환해주는 함수이다.

 

해시값을 받은 후에는 파일을 저장시켜준다.

        $("#add_board").submit(function(e){
            e.preventDefault();
            let add_board = $("#add_board").serialize();
            let tidx = $("#tech_id").val();
            console.log("add_board",add_board)
            if($("#board_mode").val()=="board"){
                alert("in!")
                if(confirm('저장하시겠습니까?')){
                    $.ajax({
                        type: "POST",
                        url : 'tech/add_board',
                        data: add_board+"&tidx="+tidx,
                        success: function(r){
                            $("#add_board")[0].reset();
                            $('#addboardmodal').modal('hide');
                            $('#viewboardmodal').modal('hide');
                            $("#board_table").jsGrid("loadData");
                        }  
                    })
                }
            }else if($("#board_mode").val()=="contract"){
                alert("contract")
                if(confirm('저장하시겠습니까?')){
                    let form = $("#add_board")[0];
                    console.log("form",form);
                    let formData = new FormData(form);
                    formData.append("title",$("#title").val());
                    formData.append("content",$("#content").val());
                    formData.append("file_hash",$("#file_hash").val());
                    formData.append("tidx",$("#tech_id").val());
                    console.log("formData",formData);
        
                    $.ajax({
                        type: "POST",
                        processData: false,
                        contentType: false,
                        enctype: 'multipart/form-data',
                        url : 'tech/add_board2',
                        data : formData,
                        success: function(r){
                            let result = r.data.file_hash;
                            console.log(result);
                            $("#add_board")[0].reset();
                            $('#addboardmodal').modal('hide');
                            $('#viewboardmodal').modal('hide');
                            $("#board_table").jsGrid("loadData");
                            // $("#file_hash").val(result);
                        },
                        error: function(){
                            location.href="/error";
                        }
                    })
                }
            }
        });

이때 다른 값과 같이 저장해야 하므로 게시판의 유형에 따라 2개로 분기하여 서로다른 api를 호출한다.

 

////////////////////기술이전 
router.post('/add_board2', upload.single("contract"), async function(req,res){

	console.log("add_board2")
	let rb = req.body;
	let rf = req.file;
	console.log(rb)
		console.log(rf)
    let file_name = rf.originalname;
    let file_path = rf.path;
	let userid = req.user.userid;
	let title = rb.title[0];
	let content = rb.content[0];
	let tidx = rb.tidx;
    let file_hash = rb.file_hash;

	var sql = `sql 구문`;
	console.log("add_board")
	let inresult = await DB.Sql( sql, [ input요소들]);
	if(inresult.affectedRows > 0){
		res.send(JSONResponse.successTrue({"board_idx":inresult.insertId}))
	}else{
		res.send(JSONResponse.successFalse({"message":"에러발생"}))
	}
});

다음과 같이 값들을 받아와서 요소들을 insert해주면 파일과 함께 게시글이 저장되게 된다.

 

이때 저장 후에 form안에 있는 데이터를 삭제해주어야 다시 열었을 때 똑같은 데이터가 나오지 않기 때문에 닫기 버튼을 누를때마다 다음 함수를 실행시켜준다.

    $("#close_modal3").on("click", function(){
        $("#add_board")[0].reset();
    });

 

2. 이제 버튼을 만들어서 동의를 넣고 동의가 되면 블록체인 해시를 저장시키는 기능을 구현하겠다.

 

                              <p class="col-lg-3 col-md-9 pt-3 contract_display">블록체인 저장 동의<span style="color: red;">*</span></p>
                                    <div class="col-lg-9 col-md-9 contract_display" style="padding-top: 10px;">
                                        <p>양쪽이 모두 동의할 시 계약서가 자동으로 블록체인에 저장됩니다.</p>
                                        <button type="button" class="btn btn-primary btn-lg" id="register_agree">등록자 동의</button>
                                        <button type="button" class="btn btn-secondary btn-lg" id="broker_agree">중개자 동의</button>
                                    </div>

먼저 버튼을 2개 추가한 후 

$('').attr('disabled', true); 
$('').attr('disabled', false);

다음 2개의 버튼을 넣고 DB 조회 후에 중개자 회원일 경우 중개자 동의를 활성화, 등록자의 경우 등록자 동의를 활성화 시킬 예정이다. 또한 텍스트로 상대방의 동의 여부를 보여줄 예정이다. 일단 DB에 칼럼을 2개를 추가해서 각각 등록자동의 중개자 동의를 저장시킬 공간을 만든 후. DB에서 조회해 와서 표시해주는걸 게시글을 띄울때 자동으로 실행시켜주고 버튼을 누를 수 있는경우 버튼을 활성화 시켜주고, 아닌 경우 비활성화를 시켜준후 버튼을 눌렀을 때 저장하는 기능을 실행하도록 만들 예정이다.

 

3. DB에 행 추가 (보안문제로 설명생략)

DB에 행을 추가하고 aquery tool에도 똑같이 추가해주어야 한다.

 

4. DB에 값이 기록되어 있을 경우 게시판을 여는 함수에 동의 정보 추가

$("#contract_view_check").val("Y");
$("#contract_hash").val(contract_hash);
if(register_agree=="Y"){
$("#register_agree").val()=="Y"
}

}
if(broker_agree=="Y"){
$("#broker_agree").val()=="Y"

5. 동의 버튼을 누를시 값 추가

<p style="display: none;" id="register_agree"></p>
<p style="display: none;" id="broker_agree"></p>
<button type="button" class="btn btn-primary btn-lg" id="register_agree_btn">등록자 동의</button>
<button type="button" class="btn btn-secondary btn-lg" id="broker_agree_btn">중개자 동의</button>

display none으로 해둔 뒤 버튼 id 추가 

 

 

728x90
반응형
Comments